我有2台机器在vs 2010上运行F#2.0 Interactive build 4.0.30319.1。我的一些程序在速度更快的机器上运行得慢得多。问题似乎是32位Windows上的整数运算性能明显慢于64位Windows。
在速度稍慢的Windows 7 64位计算机上(程序如下所示):
primeCount = 1270607
Real:00:00:07.553,CPU:00:00:07.519,GC gen0:0,gen1:0,gen2:0
在速度稍快的Windows XP SP2计算机上:
primeCount = 1270607
Real:00:00:32.800,CPU:00:00:32.796,GC gen0:0,gen1:0,gen2:0
因此,32位版本的使用时间是64位版本的4倍。我假设由于操作系统不同而没有显着差异,因此比支持的字长更短。
程序:
let isPrime(n) =
if n < 2 then false
elif (n % 2) = 0 then // take care of even case
if n = 2 then true
else false
else // n is odd
let ms = int(sqrt(float(n)))
let rec isPrimeUtil(m) =
if m > ms then true
elif n % m = 0 then false
else isPrimeUtil(m + 2)
isPrimeUtil(3)
let nums = [1 .. 20000000]
let pcountref = ref 0 // # of primes found
let primeCount =
pcountref := 0
for x in nums do
if (isPrime x) then incr pcountref
do primeCount
printfn "primeCount = %d" !pcountref
将程序发送到互动。 #time;;
然后,要测量处理的经过时间,而不是范围内容的生成,请选择行
let pcountref = ref 0
以及所有后续行并发送到交互式。
答案 0 :(得分:3)
我认为更可能的解释是64位JIT执行尾部调用优化,32位JIT不执行。 isPrimeUtil
功能可以优化
请注意,给定的示例不使用BigInteger,也有算法改进的空间 - 筛子运行得更快
答案 1 :(得分:1)
float
是64位,因此sqrt(float(n))
调用可能是您的性能接收器。 (并且会解释为什么64位机器能够更好地处理它。)
如果您不需要/精度,请尝试使用float32。
请参阅:http://msdn.microsoft.com/en-us/library/dd233210.aspx
我没有32位机器可供测试,但在我的64位机器上测试sqrt代码需要一段合理的时间。
let nums = [1 .. 20000000]
let ans = List.map (fun n -> int(sqrt(float(n))) nums
给出实时5.120秒 - 这是执行时间的重要部分。
答案 2 :(得分:0)
这些结果很有意义。 BigNum实现经常使用机器整数,直到它们检测到溢出,然后切换到更复杂的表示。 64位整数可以容纳比32位整数大得多的值。你的测试程序在64位运行时可能会花更多的时间在快速机器算术上进行测试。