web-dev-qa-db-de.com

Warum ist PHP7 bei der Ausführung dieser einfachen Schleife so viel schneller als Python3?

Als extrem einfachen Benchmark habe ich den folgenden einfachen Code auf PHP 7.0.19-1 und Python 3.5.3 (Befehlszeile) auf demselben Raspberry Pi 3-Modell B ausgeführt.

Pythons Ausführungszeit war horrible im Vergleich zu PHP (74 Sekunden gegenüber 1,4 Sekunden). Kann mir jemand helfen zu verstehen, warum die Ausführung von Python so viel länger dauert? Gibt es etwas, was ich falsch mache, oder einige Optimierungen/Einstellungen, die die Leistung verbessern, um die von PHP zu erreichen oder zu übertreffen? Oder ist Python so viel langsamer (sicherlich nicht!)?

Ja, ich habe diesen Benchmark gesehen, der PHP 7 über die anderen Sprachen hinwegbrennt, aber man könnte meinen, beide wären bei einer so einfachen Operation ziemlich gleichermaßen optimiert.

Python führt die Schleife etwa doppelt so schnell aus, wenn die Hinzufügung durch eine Stringzuweisung ersetzt wird. Das sind aber immer noch 34 Sekunden vs. 1,1 Sekunden.

PHP7-Code:

<?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);

Ergebnisse: Zeit für 100000 war 0,036377191543579 Zeit für 1000000 war 0,18501400947571 Zeit für 10000000 war 1,3399099311829

Python3-Code:

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))

Ergebnisse: Die Zeit für 1000000 war 0,761641, 1000000 die Zeit für 10000000 war 7,427618000000001, 10000000 die Zeit für 100000000 war 74,320387

7
Ryan Griggs

Sie liegen beide innerhalb einer Größenordnung voneinander, wenn Sie sie mit identischen Zykluszahlen ausführen, anstatt dass die Pythonzahlen um eine Größenordnung größer sind:

PHP: https://ideone.com/3ebkai 2.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/pRFVfk 4.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))
8
Amber

Die Schleife selbst scheint in CPython 3 doppelt so langsam zu sein:

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)))

Dies ist jedoch nur die Standardimplementierung von Python, bei der es weniger darauf ankommt, einfach zu verstehen als schnell zu sein. PyPy3.5 v6.0.0 Zum Beispiel führt diese leere Schleife in 0.06s anstelle von 1.70s auf meinem Laptop aus.

1
Cees Timmerman

Ihr seid nicht fair. Die beiden Teile des Codes machen NICHT dasselbe.

Während PHP nur zwei Variablen ($ a und $ i) inkrementiert, generiert Python vor der Schleife einen Bereich.

Um einen fairen Vergleich zu haben, sollte Ihr Python-Code also Folgendes sein:

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

Aaaaaaand, es ist viel schneller:

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

VS

>>> print(test2(100000000))
Time for 100000000 was 3.079545
1
Rafael Beckel