问题描述
几天以来,我一直在使用AutoBench,在不同的输入尺寸下测试Euler筛的性能。
我的测试只是要求在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个质数进行回答所需的时间执行有关,但是我没有在网上找到任何东西,但是官方文档中没有提及任何东西。
解决方法
经过一些分析,我发现对于大于7000的n,欧拉过程会迅速使撞锤饱和,从而导致Criterion崩溃。
克服此问题的唯一方法是提高内存或切换到其他算法/实现。