python haskell 使用对比_python - 与Project Euler的速度比较:C vs Python vs Erlang vs Haskell - 堆栈内存溢出...

我将Project Euler中的问题#12作为编程练习并比较了我在C,Python,Erlang和Haskell中的(当然不是最优的)实现。 为了获得更高的执行时间,我搜索第一个三角形数字,其中有超过1000个除数而不是原始问题中所述的500。

结果如下:

C:

lorenzo@enzo:~/erlang$ gcc -lm -o euler12.bin euler12.c

lorenzo@enzo:~/erlang$ time ./euler12.bin

842161320

real 0m11.074s

user 0m11.070s

sys 0m0.000s

蟒蛇:

lorenzo@enzo:~/erlang$ time ./euler12.py

842161320

real 1m16.632s

user 1m16.370s

sys 0m0.250s

Python与PyPy:

lorenzo@enzo:~/Downloads/pypy-c-jit-43780-b590cf6de419-linux64/bin$ time ./pypy /home/lorenzo/erlang/euler12.py

842161320

real 0m13.082s

user 0m13.050s

sys 0m0.020s

二郎:

lorenzo@enzo:~/erlang$ erlc euler12.erl

lorenzo@enzo:~/erlang$ time erl -s euler12 solve

Erlang R13B03 (erts-5.7.4) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.4 (abort with ^G)

1> 842161320

real 0m48.259s

user 0m48.070s

sys 0m0.020s

哈斯克尔:

lorenzo@enzo:~/erlang$ ghc euler12.hs -o euler12.hsx

[1 of 1] Compiling Main ( euler12.hs, euler12.o )

Linking euler12.hsx ...

lorenzo@enzo:~/erlang$ time ./euler12.hsx

842161320

real 2m37.326s

user 2m37.240s

sys 0m0.080s

摘要:

C:100%

Python:692%(使用PyPy时为118%)

Erlang:436%(135%归功于RichardC)

哈斯克尔:1421%

我认为C有一个很大的优势,因为它使用long进行计算而不是任意长度整数作为其他三个。 此外,它不需要首先加载运行时(其他人?)。

问题1: Erlang,Python和Haskell是否由于使用任意长度整数而失去速度,或者只要值小于MAXINT就不会失败?

问题2:为什么Haskell这么慢? 是否有编译器标志关闭刹车或是我的实施? (后者非常可能,因为Haskell是一本带有七个印章的书。)

问题3:您能否提供一些提示,如何优化这些实现而不改变我确定因素的方式? 以任何方式进行优化:更好,更快,更“本地”的语言。

编辑:

问题4:我的功能实现是否允许LCO(最后调用优化,也就是尾递归消除),从而避免在调用堆栈中添加不必要的帧?

我真的试图在四种语言中尽可能地实现相同的算法,尽管我必须承认我的Haskell和Erlang知识非常有限。

使用的源代码:

#include

#include

int factorCount (long n)

{

double square = sqrt (n);

int isquare = (int) square;

int count = isquare == square ? -1 : 0;

long candidate;

for (candidate = 1; candidate <= isquare; candidate ++)

if (0 == n % candidate) count += 2;

return count;

}

int main ()

{

long triangle = 1;

int index = 1;

while (factorCount (triangle) < 1001)

{

index ++;

triangle += index;

}

printf ("%ld\n", triangle);

}

#! /usr/bin/env python3.2

import math

def factorCount (n):

square = math.sqrt (n)

isquare = int (square)

count = -1 if isquare == square else 0

for candidate in range (1, isquare + 1):

if not n % candidate: count += 2

return count

triangle = 1

index = 1

while factorCount (triangle) < 1001:

index += 1

triangle += index

print (triangle)

-module (euler12).

-compile (export_all).

factorCount (Number) -> factorCount (Number, math:sqrt (Number), 1, 0).

factorCount (_, Sqrt, Candidate, Count) when Candidate > Sqrt -> Count;

factorCount (_, Sqrt, Candidate, Count) when Candidate == Sqrt -> Count + 1;

factorCount (Number, Sqrt, Candidate, Count) ->

case Number rem Candidate of

0 -> factorCount (Number, Sqrt, Candidate + 1, Count + 2);

_ -> factorCount (Number, Sqrt, Candidate + 1, Count)

end.

nextTriangle (Index, Triangle) ->

Count = factorCount (Triangle),

if

Count > 1000 -> Triangle;

true -> nextTriangle (Index + 1, Triangle + Index + 1)

end.

solve () ->

io:format ("~p~n", [nextTriangle (1, 1) ] ),

halt (0).

factorCount number = factorCount' number isquare 1 0 - (fromEnum $ square == fromIntegral isquare)

where square = sqrt $ fromIntegral number

isquare = floor square

factorCount' number sqrt candidate count

| fromIntegral candidate > sqrt = count

| number `mod` candidate == 0 = factorCount' number sqrt (candidate + 1) (count + 2)

| otherwise = factorCount' number sqrt (candidate + 1) count

nextTriangle index triangle

| factorCount triangle > 1000 = triangle

| otherwise = nextTriangle (index + 1) (triangle + index + 1)

main = print $ nextTriangle 1 1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值