Incidentally, @lagerratrobe, once you save a lot of time by replacing sorting 
by a perfect commutative hash, the next optimization is making the IO part 
faster (you need cligen-0.9.43 for this): 
    
    
    import strutils, tables, cligen/[mfile, mslice]
    
    const prime: array[26, uint64] = [ #9/267751 oflow
      7'u64, 61, 41, 53, 2, 71, 47, 29, 3, 97, 89, 17, 59,
      19, 5, 31, 101, 11, 13, 23, 37, 79, 73, 67, 43, 83 ]
    
    proc product(word: MSlice): uint64 =
      result = 1'u64      #Assumes whole file is uppercase
      for ch in word:     #iterator needs cligen>=0.9.43
        result *= prime[ord(ch) - ord('A')]
    
    proc pBuildQry(dict="words", query: seq[string]) =
      var anas = initTable[uint64, seq[MSlice]]()
      let mf = mopen(dict)
      if mf == nil: return
      defer: mf.close
      for word in mf.mSlices():
        anas.mgetOrPut(word.product, @[]).add word
      for word in query:
        let word = word.toUpperAscii
        let prod = word.toMSlice.product
        echo word, ":"
        try:
          for ana in anas[prod]: echo "  ", ana
        except: discard
    import cligen; dispatch(pBuildQry)
    
    
    Run

With that my 129 ms goes down by 57ms to 72 ms (1.8x better) on that SOWPODS 
dictionary. Then if you Nim compile with `--gc:arc`, it goes down to about 47 
ms (1.53x better). Then if you use gcc's PGO it goes down to 42 ms (1.12x 
better).

I suspect with your dictionary and CPU that you would see a similar overall 4x 
to 5x improvement taking you from 286 ms down to more like <70ms. Language 
comparison-wise, I do not believe R or CPython would be able to be sped up 
similarly. (Perhaps in PyPy the product might be able to become fast, but 
perhaps not if they are worrying about overflow switching to arbitrary 
precision ints.)

Reply via email to