python - 为什么这段 Haskell 代码这么慢?

标签 python haskell optimization language-comparisons

我是 Haskell 的新手,尝试制作一个拼字游戏求解器。它接受您当前拥有的字母,找到它们的所有排列并过滤掉那些字典单词。代码非常简单:

import Data.List

main = do
    dict    <- readFile "words"
    letters <- getLine
    let dictWords = words dict
    let perms = permutations letters
    print [x | x <- perms, x `elem` dictWords]

然而,与我使用 Python 进行的非常相似的实现相比,它的速度非常慢。我做错了什么基本的事情吗?

*编辑:这是我的 Python 代码:

from itertools import permutations

letters = raw_input("please enter your letters (without spaces): ")

d = open('words')
dictionary = [line.rstrip('\n') for line in d.readlines()]
d.close()

perms = ["".join(p) for p in permutations(letters)]

validWords = []

for p in perms:
    if p in dictionary: validWords.append(p)


for validWord in validWords:
    print validWord

我没有对它们进行精确计时,但大致感觉 Python 实现的速度大约是 Haskell 实现的 2 倍。也许我不应该说相比之下 Haskell 代码“慢得令人难以置信”,但由于 Haskell 是静态类型的,我想我只是认为它应该快得多,而且一点也不比 Python 慢。

最佳答案

I'm kind of new to Haskell and tried making a scrabble solver.

您可以通过使用更好的算法来显着改进。

不是测试输入字母的每个排列,如果你 首先对它们进行排序,您只能进行一次字典查找并获得 所有可能的单词(字谜)可能由 他们(使用所有这些)。

这是将字典创建为 Data.Map 的代码。 创建 map 需要启动成本,但之后 第一个查询后续查找非常快。

import Data.List
import qualified Data.Map.Strict as Map
import Control.Monad
import System.IO

main = do
  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 $ do
    putStr "Enter letters: " >> hFlush stdout
    letters <- getLine
    case Map.lookup (sort letters) dict of
      Nothing -> putStrLn "No words."
      Just ws -> putStrLn $ "Words: " ++ show ws

一个 236K 字 (2.5 MB) 的字文件的 map 创建时间约为 4-5 秒。使用 ByteString 或 Text 而不是 String 可能会获得更好的性能。

尝试一些不错的字母组合:

steer rat tuna lapse groan neat

注意:使用 GHC 7.10.2 我发现此代码在使用 -O2 进行编译时表现最佳。

关于python - 为什么这段 Haskell 代码这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39283047/

相关文章:

python - Keras Python 脚本有时运行良好,有时会因 Matrix size-incompatible : In[0]: [10000, 1]、In[1] : [3, 1] 而失败

python - 使用 Torch 进行数值优化,让优化器得到一个空参数列表,

python - Pandas 数据框中所有系列的唯一值计数的总和

haskell - 由于使用 ‘a0’ 而产生的不明确类型变量 ‘param’ 阻止了约束 ‘(Parsable a0)’ 的求解

haskell - 如何获取 Cabal/Stack 发出的 GHC 命令?

haskell - 找不到模块 Prelude... 包基础的 dyn 库?

python - PSO 能否收敛于导数非零的点?

python - 如何在Python中的同一个数组中添加不同的元素?

python - 我应该如何使用 GEKKO 为 log 或 sqrt 建模?约束条件

readability - 我将如何简化这段代码?