Pull to refresh

Честное тестирование скорости PHP и Python

Programming *
Добрый день.
Все мы знаем что качество и скорость кода зависит от программиста. Хороший программист может умело пользоваться сильными и слабыми сторонами своего ЯП.
В прошлый раз PHP показал свою сильную сторону — числа это числа. В Python числа это объекты.
Значит для объективного теста нужно что бы PHP тоже считал математические объекты.

Методика тестирования

Хорошими математическими объектами являются комплексные числа, в PHP и в Python комплексные числа будут представлены объектами. За основу я взял тест с наивным поиском простых чисел и код написанный Thomas Vander Stichele, только вместо целых чисел используются действительные числа из комплексного числа. Главное что соблюдается условие что в двух языках используются объекты.

Я постарался сделать код наиболее похожим друг на друга, что бы соблюдать объективность теста. По-этому не использовал различные хитрые оптимизации которые знаю для Python и не знаю для PHP. В Python есть встроенный класс комплексных чисел, но для объективности теста класс комплексных чисел написан похожим на PHP вариант и с минимальным функционалом.

Получившийся код такой:

PHP
#!/usr/bin/env php
<?php
class Complex {
    public $real = 0;
    private $imag = 0;
    public function __construct($real, $imag = null) {
        $this->real = (float)$real;
    }
    public function __toString() {
        return sprintf("(%d+%dj)", $this->real, $this->imag);
    }
}

$start = microtime(TRUE);
$primeNumbers = array();
$output = '';

for ($i = 2; $i < 100000; $i++) {
    $divisible = false;
    $in = new Complex($i);
    foreach($primeNumbers as $number) {
        if ($in->real % $number->real == 0) {
            $divisible = true;
            break;
        }
    }
    if ($divisible == false){
        $primeNumbers[] = $in;
        $output .= $in;
    }
}

echo "time: ", microtime(TRUE) - $start, "\n";
echo count($primeNumbers), " ", strlen($output), "\n";
?>


Python
#!/usr/bin/env python
import time

class Complex(object):
    def __init__(self, real, imag=None):
        self.real = real
        self.imag = 0

    def __str__(self):
        return "({0}+{1}j)".format(self.real, self.imag)

start = time.time()
primeNumbers = []
output = ""

for i in xrange(2, 100000):
    divisible = False
    inum = Complex(i)

    for number in primeNumbers:
        if inum.real % number.real == 0:
            divisible = True
            break

    if divisible == False:
        primeNumbers.append(inum)
        output += str(inum)


print 'time: %f' % (time.time() - start)
print len(primeNumbers), len(output)


Тестирование

В моей тестовой среде Ubuntu 10.04 работающая в VMWare Player 3 на процессоре Celeron 1.2GHz получилось:
  • PHP 5 — 50 с;
  • Python 2.6 — 30 c.

Вывод

Если Вам нужен простой математический калькулятор — пользуйтесь PHP.
В объективных тестах Python быстрее.

Thomas Vander Stichele так же отметил что с помощью решета Эратосфена поиск простых чисел можно многократно ускорить.

PS: Буду благодарен если укажите где код не эквивалентный, только без хитрых оптимизаций.

Привет всем в группе python-django-spb, присоединяйтесь пожалуйста тоже.
Tags:
Hubs:
Total votes 57: ↑24 and ↓33 -9
Views 18K
Comments Comments 37