python - Why is this Haskell code so slow? -


i'm kind of new haskell , tried making scrabble solver. takes in letters have, finds permutations of them , filters out dictionary words. code's pretty simple:

import data.list  main =     dict    <- readfile "words"     letters <- getline     let dictwords = words dict     let perms = permutations letters     print [x | x <- perms, x `elem` dictwords] 

however it's incredibly slow, compared similar implementation have python. there fundamental i'm doing wrong?

*edit: here's python code:

from itertools import permutations  letters = raw_input("please enter letters (without spaces): ")  d = open('words') dictionary = [line.rstrip('\n') line in d.readlines()] d.close()  perms = ["".join(p) p in permutations(letters)]  validwords = []  p in perms:     if p in dictionary: validwords.append(p)   validword in validwords:     print validword 

i didn't time them precisely, feels python implementation 2x fast haskell one. perhaps should't have said haskell code "incredibly slow" in comparison, since haskell statically typed guess thought should've been faster, , not slower python @ all.

i'm kind of new haskell , tried making scrabble solver.

you can substantially improve things using better algorithm.

instead of testing every permutation of input letters, if sort them first can make 1 dictionary lookup , of possible words (anagrams) may formed them (using of them).

here code creates dictionary data.map. there start-up cost creating map, after first query subsequent lookups fast.

import data.list import qualified data.map.strict map import control.monad import system.io  main =   contents <- readfile "words"   let pairs = [ (sort w, [w]) | w <- words contents ]       dict = foldl' (\m (k,v) -> map.insertwith (++) k v m) map.empty pairs       -- dict = foldr (\(k,v) m -> map.insertwith (++) k v m) map.empty pairs   forever $     putstr "enter letters: " >> hflush stdout     letters <- getline     case map.lookup (sort letters) dict of       nothing -> putstrln "no words."       ws -> putstrln $ "words: " ++ show ws 

map creation time word file of 236k words (2.5 mb) 4-5 seconds. better performance possible using bytestrings or text instead of strings.

some letter combinations try:

steer rat tuna lapse groan neat 

note: using ghc 7.10.2 found code performed best without compiling -o2.


Comments