为什么PHP7执行这个简单循环比Python3快得多?

2024-09-28 22:22:01 发布

您现在位置:Python中文网/ 问答频道 /正文

作为一个非常简单的基准测试,我在PHP 7.0.19-1和Python 3.5.3(命令行)上对同一个Raspberry pi3模型B执行了下面的简单代码

与PHP相比,Python的执行时间是可怕的(74秒对1.4秒)。有谁能帮我理解为什么在Python上执行要花这么长时间?是否有什么地方我做错了,或者一些优化/设置会提高它的性能以达到或超过PHP的性能?或者说Python就是那么慢(当然不是!)?

是的,我看到了this benchmark,它报告PHP 7超越了其他语言,但是您会认为在执行这样一个简单的操作时,这两种语言都会得到相当好的优化。

如果用字符串赋值代替加法,Python执行循环的速度大约是前者的两倍。但这仍然是34秒对1.1秒。

PHP7代码:

<?php

function test($x)
{
    $t1 = microtime(true);
    $a = 0;
    for($i = 0; $i < $x; $i++)
    {
        $a++;
    }
    $t2 = microtime(true);

    echo "Time for $x was " . ($t2 - $t1) . "\n";

    return $a;
}


echo test(100000);
echo test(1000000);
echo test(10000000);

结果: 10万的时间是0.036377191543579 1000000次为0.1850140947571 10000000次为1.3939099311829

Python3代码:

import time
def test(x):
    t1 = time.clock()
    a = 0
    for i in range(x):
        a += 1
    t2 = time.clock()
    print("Time for {} was {}".format(x, t2 - t1))
    return x

print(test(1000000))
print(test(10000000))
print(test(100000000))

结果: 1000000的时间是0.761641 100万 10000000的时间是7.427618000000001 1亿 100000000的时间是74.320387 1亿

更新:是的,在@Amber指出之后,我意识到我完全崩溃了,循环计数器是一个数量级的间隔。尽管如此,答案还是很有趣,所以值得一问。


Tags: 代码testecho语言truefortime时间
3条回答

它们都在一个数量级内,如果使用相同的循环计数运行它们,而不是让Python计数大一个数量级:

PHP:https://ideone.com/3ebkai2.7089s

<?php

function test($x)
{
    $t1 = microtime(true);
    $a = 0;
    for($i = 0; $i < $x; $i++)
    {
        $a++;
    }
    $t2 = microtime(true);

    echo "Time for $x was " . ($t2 - $t1) . "\n";

    return $a;
}


echo test(100000000);

Python:https://ideone.com/pRFVfk4.5708s

import time
def test(x):
    t1 = time.clock()
    a = 0
    for i in range(x):
        a += 1
    t2 = time.clock()
    print("Time for {} was {}".format(x, t2 - t1))
    return x

print(test(100000000))

在CPython 3中,循环本身的速度似乎是后者的两倍:

https://ideone.com/bI6jzD

<?php
function test($x)
{
    $t1 = microtime(true);
    $a = 0;
    for($i = 0; $i < $x; ++$i)
    {
        //1.40s Reassign and use $a.
        //$a += 1;
        //1.15s Use and increment $a.
        //$a++;
        //0.88s Increment and use $a.
        //++$a;
        //0.69s Do nothing.
    }
    $t2 = microtime(true);
    echo "Time for $x was " . ($t2 - $t1) . "\n";
    return $a;
}
echo test(1e8);

https://ideone.com/l35EBc

import time

def test(x):
    t1 = time.clock()
    #>5s
    #from functools import reduce
    #a = reduce(lambda a, i: a + i, (1 for i in range(x)), 0)
    a = 0
    for i in range(x):
        #4.38s
        #a += 1
        #1.89s
        pass
    t2 = time.clock()
    print("Time for {} was {}".format(x, t2 - t1))
    return x

print(test(int(1e8)))

然而,这只是Python的标准实现,它更关心易懂而不是快速。PyPy3.5 v6.0.0例如,在我的笔记本电脑上运行0.06秒而不是1.70秒的空循环。

你们不公平。这两段代码做的不是同一件事。

虽然PHP只增加两个变量($a和$i),但Python在循环之前生成一个范围。

因此,要进行公平的比较,您的Python代码应该是:

import time
def test2(x):
    r = range(x) #please generate this first
    a = 0

    #now you count only the loop time
    t1 = time.clock()
    for i in r:
        a += 1
    t2 = time.clock()

    print("Time for {} was {}".format(x, t2 - t1))
    return a

啊啊啊,速度快多了:

>>> print(test(100000000))
Time for 100000000 was 6.214772

>>> print(test2(100000000))
Time for 100000000 was 3.079545

相关问题 更多 >