Python vs PHP速度

Python vs PHP速度,php,python,Php,Python,我想从中解决一个问题(顺便说一句,问题25),我在Python中找到了一个解决方案: fibonacci = 1 old1 = 0 old2 = 1 limit = 1000 i = 1 while len(str(fibonacci)) < limit: fibonacci = old1 + old2 old1 = old2 old2 = fibonacci i = i + 1 print(i) fibonacci=1 old1=0 old2=1

我想从中解决一个问题(顺便说一句,问题25),我在Python中找到了一个解决方案:

fibonacci = 1
old1 = 0
old2 = 1
limit = 1000

i = 1

while len(str(fibonacci)) < limit:
    fibonacci = old1 + old2
    old1 = old2
    old2 = fibonacci
    i = i + 1

print(i)
fibonacci=1
old1=0
old2=1
限额=1000
i=1
而len(str(fibonacci))<极限:
斐波那契=old1+old2
old1=old2
old2=斐波那契
i=i+1
印刷品(一)
计算耗时1.5秒

我在PHP中实现了相同的功能,代码如下:

$fibonacci = 1;
$old1 = 0;
$old2 = 1;
$limit = 1000;

$i = 1;

while (strlen((string)$fibonacci) < $limit){
    $fibonacci = $old1 + $old2;
    $old1 = $old2;
    $old2 = $fibonacci;
    $i = $i + 1;
}
print($i);
$fibonacci=1;
$old1=0;
$old2=1;
$limit=1000;
$i=1;
while(strlen((字符串)$fibonacci)<$limit){
$fibonacci=$old1+$old2;
$old1=$old2;
$old2=$fibonacci;
$i=$i+1;
}
印刷(一美元);
花了30多分钟,还在计算

我知道Python被认为比PHP快,但它仍然不应该有太大的区别。如果有办法的话,如何改进我的PHP代码以更快地获得结果

编辑:

我根据下面的评论编辑了这篇文章,所以首先我的解决方案不起作用。 一种解决方案可以替代旧的解决方案,而要将此解决方案:

while (strlen(number_format($fibonacci, 0, '', '')) < $limit){ ... }
while(strlen(数字格式($fibonacci,0,,'')<$limit){…}
但这也是一个很大的速度问题

因此,最终的解决方案是使用:

$fibonacci='1';
$old1='0';
$old2='1';
$limit=1000;
$i=1;
while(strlen($fibonacci)<$limit){
$fibonacci=bcadd($old1,$old2);
$old1=$old2;
$old2=$fibonacci;
$i=$i+1;
}
echo$fibonacci。“
”; 印刷(一美元);

因此,您可以在PHP中以与Python相同的速度获得结果。

这不是速度问题,而是终止while条件下的逻辑问题


它可能不会结束。当您在while测试中将$fibonacci的当前值转换为字符串时,将其转换为科学格式,并在将其转换为字符串时将其截断为有限的小数位数集(取决于精度设置)。这个数字将大大少于1000,因此while终止条件将永远无法满足。

毫无疑问,PHP将进入无限循环。如果没有什么不对劲,不可能花那么长时间

我认为用
strlen
计算这些数字的位数在PHP中是行不通的。PHP用科学记数法处理数字,精度低于Python

我在PHP中添加了调试
echo
语句,以便为每个步骤打印$fibonacci和$I

典型的Python行如下所示

fib is 7540113804746346429
i is 92
在PHP中,这是

fib is 7.54011380475E+18
i is 92
要在PHP中实现这一点,可能需要使用精度更高的数学库


签出-您可以使用
bcadd
函数来完成添加,它的工作方式与Python中的相同。

由于问题似乎在于转换为字符串,因此这里有一种更快的方法,不需要它。这基本上与您发布的算法相同(因此我向您展示它并不感到不舒服),但演示了如何使用除法测试整数的长度,而不是将其转换为字符串

def fibonacci_digits(limit):
    limit = 10**limit
    fib = 1
    old1 = 0
    old2 = 1

    i = 1
    size = 1
    while size < limit:
        fib = old1 + old2
        if not size//fib:  # // is pythons integer division operator, not a comment
            size *= 10
        old1 = old2
        old2 = fib
        i += 1

    return i

print fibonacci_digits(1000)

许多project Euler问题将不得不处理大量数据。 PHP将使您的大数字看起来像
2.579234678963E+12
,这是数字的指数表示。。。这显然很难相处。 所以,对于大多数问题,最好是随大流。这将保持你的数字不变,即使它是一个巨大的数字

注意使用
echo bcmul(500500)
的速度永远不会像echo 500*500那么快。而且,BCMath函数返回值始终是字符串


要解决问题,请使用相应的BCMath函数替换所有算术运算

问题是,你在处理大数字。您应该使用BC数学函数()。因此,您的代码可以是:

$fibonacci = "1";
$old1 = "0";
$old2 = "1";
$limit = 1000;

$i = 1;

while (strlen($fibonacci) < $limit){
    $fibonacci = bcadd($old1, $old2);
    $old1 = $old2;
    $old2 = $fibonacci;
    $i = $i + 1;
}
print($i);
$fibonacci=“1”;
$old1=“0”;
$old2=“1”;
$limit=1000;
$i=1;
while(strlen($fibonacci)<$limit){
$fibonacci=bcadd($old1,$old2);
$old1=$old2;
$old2=$fibonacci;
$i=$i+1;
}
印刷(一美元);

我已经试过了,大约需要0.095秒。

我对Python代码进行了一些优化。使用len(str())检查位数非常慢。替换为math.log10运行程序要快得多

斐波那契序列中包含1000位数字的第一项是:4782 计算时间为0.008573秒

导入时间
从数学导入日志10
def digits(n):#返回n>=1的位数
返回整数(log10(n))+1
fibonacci=1L#多亏了Python处理非常大的数字
old1=0
old2=1
限额=1000
i=1
开始=时间。时间()#工作台启动计时器
而数字(斐波那契)<极限:
斐波那契=old1+old2
old1=old2
old2=斐波那契
i+=1
打印“斐波那契序列中包含%s个数字的第一个项是:%s”%(str(limit),str(i))
打印“以%3.6f秒计算”%(time.time()-start)
$ python -mtimeit -s'import fib' 'fib.fibonacci_digits(1000)'
10 loops, best of 3: 30.2 msec per loop

$ python -mtimeit -s'import fib' 'fib.fibonacci_digits2(1000)'
10 loops, best of 3: 1.41 sec per loop
$fibonacci = "1";
$old1 = "0";
$old2 = "1";
$limit = 1000;

$i = 1;

while (strlen($fibonacci) < $limit){
    $fibonacci = bcadd($old1, $old2);
    $old1 = $old2;
    $old2 = $fibonacci;
    $i = $i + 1;
}
print($i);
import time
from math import log10


def digits(n): # Return the number of digits for n>=1
    return int(log10(n))+1

fibonacci = 1L # Thanks to Python to handle very big numbers
old1 = 0
old2 = 1
limit = 1000

i = 1


start = time.time() #Start timer for bench
while digits(fibonacci) < limit:
    fibonacci = old1 + old2
    old1 = old2
    old2 = fibonacci
    i +=  1



print "The first term in the Fibonacci sequence to contain %s digits is : %s" % (str(limit), str(i))

print "Calculated in %3.6f seconds" %  (time.time() - start)