Hi All,

I read about Nim for the 1st time last week and decided to make something over 
the weekend. I was pleasantly surprised that I was able to cobble something 
together that did what I wanted it to do, but am a bit surprised that it's not 
faster. Maybe some of you could give some suggestions on how to improve 
performance?

The goal was to write a program that takes a word as input from the user, reads 
a local file of dictionary words, and returns all of the words in the 
dictionary that are anagrams of the user’s original word.

The code I came up with is this.
    
    
    # anagram_redux.nim
    
    # ---- Imports 
----------------------------------------------------------------#
    import strutils
    import algorithm
    import os
    import strformat
    import tables
    import unidecode
    
    # ---- Converts a word into it's lower-case, sorted "signature" 
---------------#
    proc makeSignature(word: string): string =
      let ascii = unidecode(word)
      let lower = strutils.toLowerAscii(ascii)
      let sorted_word = algorithm.sorted(lower, system.cmp)
      let signature = sorted_word.join()
      result = signature
    
    # ---- Main body of program 
---------------------------------------------------#
    proc main =
      # -- Parse the lookup word from the argument passed in
      if os.paramCount() < 1:
          quit("Usage: anagram_redux <word>")
      let lookup_word = os.paramStr(1)
      let lookup_signature = makeSignature(lookup_word)
      echo strformat.fmt("Looking up '{lookup_word}'")
      
      # -- Create empty table to store results in
      var anagram_table = tables.initTable[string, seq[string]]()
      
      # -- Open the text file and process it
      let file = open("dict.txt")
      
      for word in file.lines():
        let signature = makeSignature(word)
        if anagram_table.hasKey(signature):
          anagram_table[signature].add(word)
        else:
          anagram_table[signature] = @[word]
      
      # -- Lookup user's word via its signature in the anagram_table
      if anagram_table[lookup_signature].len == 1:
        echo strformat.fmt("'{lookup_word}' does not have any anagrams")
      else:
        echo anagram_table[lookup_signature]
    
    main()
    
    
    Run

The "dict.txt" file with dictionary words is on github at 
[https://github.com/lagerratrobe/nim_dev](https://github.com/lagerratrobe/nim_dev).
 For comparison, here are the performance numbers I get from this and similar 
implementations in Python and R.

  * Nim unoptimized


    
    
    real    0m1.809s
    user    0m1.782s
    sys     0m0.012s
    
    
    Run

  * Nim --opt:speed


    
    
    real    0m0.599s
    user    0m0.575s
    sys     0m0.016s
    
    
    Run

  * Python


    
    
    real    0m0.348s
    user    0m0.325s
    sys     0m0.020s
    
    
    Run

  * R


    
    
      user  system elapsed
      1.773   0.020   1.803
    
    
    Run

Reply via email to