几天以来,我一直在使用AutoBench测试不同输入大小的Euler筛的性能。
我的测试只是要求在欧拉筛生成的列表中找到第n个素数。
虽然Criterion在n的小输入上运行良好,但当n大于7000时,它似乎不会生成有效的报告。
这是我测试的Input.hs文件:
eS :: Int -> Int
eS x = (eulerSieve [2..]) !! x where
eulerSieve cs@(p:tcs) = p:eulerSieve (minus tcs (map (p*) cs))
tDat :: UnaryTestData Int
tDat =
[ (1000, return 1000)
, (2000, return 2000)
, (3000, return 3000)
, (4000, return 4000)
, (5000, return 5000)
, (6000, return 6000)
, (7000, return 7000)
, (8000, return 8000)
, (9000, return 9000)
, (10000, return 10000)
, (11000, return 11000)
, (12000, return 12000)
, (13000, return 13000)
, (14000, return 14000)
, (15000, return 15000)
, (16000, return 16000)
, (17000, return 17000)
, (18000, return 18000)
, (19000, return 19000)
, (20000, return 20000)
]
ts :: TestSuite
ts = def {
_progs = ["eS"],
_dataOpts = Manual "tDat"
}
这就是我得到的错误:
benchmarking Input Size 8000/Input.eS
• Executed benchmarking file ✔
• Generating test report
File error: Invalid Criterion report: Error in $: not enough input
Testing cancelled. Press any key to exit...
Leaving AutoBench.
我认为这与程序用第n个素数回答所需的时间执行有关,但我在网上没有找到任何东西,只有官方文件没有提到它。
经过一些分析后,我发现对于n大于7000的情况,Euler过程会迅速使ram饱和,从而导致Criterion崩溃。
克服这个问题的唯一方法是增加ram或切换到不同的算法/实现。