2016-04-13 3 views
2

Я попытался бенчмарка короткий код из here преобразования непосредственно из JavaScript в PHPКак ускорить математику PHP?

Javascript:

(function() { 
    var a = 3.1415926, b = 2.718; 
    var i, j, d1, d2; 
    for(j=0; j<10; j++) { 
     for(i=0; i<100000000; i++) { 
      a = a + b; 
     } 
    } 
    console.log("a = " + a); 
})(); 

PHP:

<?php 

$a = 3.1415926; 
$b = 2.718; 

for($j=0; $j<10; $j++) { 
    for($i=0; $i<100000000; $i++) { 
     $a = $a + $b; 
    } 
} 
echo "a = $a\n"; 

Запуск и на консоли (мой терминал Macbook, узел v5.7.0 по сравнению с PHP 7.0.4), результаты довольно озадачивают:

$ time node test.js 
a = 2717999973.76071 

real 0m1.340s 
user 0m0.912s 
sys 0m0.021s 

$ time php t.php 
a = 2717999973.7607 

real 2m40.239s 
user 2m35.271s 
sys 0m0.507s 

Действительно ли PHP в основных математических операциях 120 раз медленнее чем узел? Есть ли что-то, что можно сделать, чтобы оптимизировать это?

Это

+3

Важно помнить, где работает код. С помощью php ресурсы извлекаются с вашего сервера хостинга. Медленный процессор и медленная память на сервере вызовут медленный PHP-код. Javascript math запускается с пользовательского компьютера через свой браузер с помощью интерпретатора. Математика в Javascript зависит от скорости работы пользователей. – jjonesdesign

+3

@jjonesdesign Как указано на вопрос, я запускаю их обоих на моем терминале Macbook. Оба они исполняются как сценарии оболочки, а не браузер на сервере клиента на удаленном хосте. – pistacchio

+1

Бенчмаркинг PHP/Javascript точно может быть довольно самостоятельной задачей, я бы начал с того, что показал нам, как вы произвели эти цифры – RiggsFolly

ответ

-2

различие скорости Math для ваших результатов приходят от нескольких факторов.

Главным образом, Javascript запускается от конечного пользователя, и скорости будут зависеть от этой машины.

В php код запускается из ресурсов сервера и, следовательно, зависит от его способностей (главным образом центрального процессора), чтобы хруст этих чисел.

В большинстве случаев PHP чаще всего страдает от ресурсов серверов, так как многие поставщики переполняют свою среду.

Albeit, Php будет немного медленнее с любой особой проблемой, поскольку в фоновом режиме происходит гораздо больше, чем в Javascript. С JS код не запускается до загрузки всех ресурсов.

Php поручено загрузить apache, затем php, а затем интерпретировать ваш код. Таким образом, на php-сервере происходит больше вещей.

+1

Это не говорит о Javascript на стороне клиента или о PHP через веб-сервер, это два отдельных вызова CLI. – iainn

+0

Я, конечно, не ожидаю, что это будет выбранный ответ, но отправлен для тех, кто споткнется на это, ища альтернативу. – jjonesdesign

+1

Вы описываете общую скорость выполнения кода на клиенте и код на сервере. Как указано в других комментариях и в вопросе, я запускаю их как сценарии оболочки на той же машине. – pistacchio

2

Хотя я не могу объяснить огромную разницу между javascript и PHP, я смог заставить обработку кода PHP работать на 30% быстрее за одно небольшое изменение.

После запуска несколько тестов на местном уровне, я обустроенные изменения

$a = $a + $b; 

в

$a += $b; 

дал время работы на 53-55 секунд, по сравнению с 78-80 (на моей машине - i5 8 ГБ оперативной памяти и медленный диск). Использование сэкономленной оценки (округленная до 25%) должна привести к обработке в течение примерно 2 минут. Очевидно, что это не так близко к времени JavaScript.

В зависимости от того, что вы реально хотите запускать (поскольку только для бенчмаркинга столько всего сказано) могут быть другие улучшения, которые вы можете сделать, но не всегда для таких больших чисел.

2

JavaScript компилируется почти 1: 1, поэтому 10^9 циклов с небольшим количеством плоти в нем работают так же быстро, как позволяет процессор (здесь: 2.14 с. Со старым узлом, версия v0.10.25).

PHP с другой стороны делает многое, особенно машину Zend. Если вы сбрасываете op-коды вашей маленькой программы с VLD, вы получаете (php 7.0.5):

$ php -d vld.active=1 -d vld.execute=0 -f benchmark.php 

Finding entry points 
Branch analysis from position: 0 
Jump found. Position 1 = 14 
Branch analysis from position: 14 
Jump found. Position 1 = 16, Position 2 = 4 
Branch analysis from position: 16 
Jump found. Position 1 = -2 
Branch analysis from position: 4 
Jump found. Position 1 = 10 
Branch analysis from position: 10 
Jump found. Position 1 = 12, Position 2 = 6 
Branch analysis from position: 12 
Jump found. Position 1 = 16, Position 2 = 4 
Branch analysis from position: 16 
Branch analysis from position: 4 
Branch analysis from position: 6 
Jump found. Position 1 = 12, Position 2 = 6 
Branch analysis from position: 12 
Branch analysis from position: 6 
filename:  benchmark.php 
function name: (null) 
number of ops: 21 
compiled vars: !0 = $a, !1 = $b, !2 = $j, !3 = $i 
line  #* E I O op       fetch   ext return operands 
------------------------------------------------------------------------------------- 
    2  0 E > ASSIGN             !0, 3.14159 
    3  1  ASSIGN             !1, 2.718 
    5  2  ASSIGN             !2, 0 
     3  > JMP              ->14 
    6  4 > ASSIGN             !3, 0 
     5  > JMP              ->10 
    7  6 > ADD            ~8  !0, !1 
     7  ASSIGN             !0, ~8 
    6  8  POST_INC           ~10  !3 
     9  FREE              ~10 
     10 > IS_SMALLER          ~11  !3, 100000000 
     11  > JMPNZ             ~11, ->6 
    5 12 > POST_INC           ~12  !2 
     13  FREE              ~12 
     14 > IS_SMALLER          ~13  !2, 10 
     15  > JMPNZ             ~13, ->4 
    10 16 > ROPE_INIT          3 ~15  'a+%3D+' 
     17  ROPE_ADD          1 ~15  ~15, !0 
     18  ROPE_END          2 ~14  ~15, '%0A' 
     19  ECHO              ~14 
     20  > RETURN             1 

branch: # 0; line:  2- 5; sop:  0; eop:  3; out1: 14 
branch: # 4; line:  6- 6; sop:  4; eop:  5; out1: 10 
branch: # 6; line:  7- 6; sop:  6; eop:  9; out1: 10 
branch: # 10; line:  6- 6; sop: 10; eop: 11; out1: 12; out2: 6 
branch: # 12; line:  5- 5; sop: 12; eop: 13; out1: 14 
branch: # 14; line:  5- 5; sop: 14; eop: 15; out1: 16; out2: 4 
branch: # 16; line: 10- 10; sop: 16; eop: 20; out1: -2 
path #1: 0, 14, 16, 
path #2: 0, 14, 4, 10, 12, 14, 16, 
path #3: 0, 14, 4, 10, 6, 10, 12, 14, 16, 

Разница между вашими двумя версиями является

1,10c1,10 
< branch: # 0; line:  2- 5; sop:  0; eop:  3; out1: 14 
< branch: # 4; line:  6- 6; sop:  4; eop:  5; out1: 10 
< branch: # 6; line:  7- 6; sop:  6; eop:  9; out1: 10 
< branch: # 10; line:  6- 6; sop: 10; eop: 11; out1: 12; out2: 6 
< branch: # 12; line:  5- 5; sop: 12; eop: 13; out1: 14 
< branch: # 14; line:  5- 5; sop: 14; eop: 15; out1: 16; out2: 4 
< branch: # 16; line: 10- 10; sop: 16; eop: 20; out1: -2 
< path #1: 0, 14, 16, 
< path #2: 0, 14, 4, 10, 12, 14, 16, 
< path #3: 0, 14, 4, 10, 6, 10, 12, 14, 16, 
--- 
> branch: # 0; line:  2- 5; sop:  0; eop:  3; out1: 13 
> branch: # 4; line:  6- 6; sop:  4; eop:  5; out1: 9 
> branch: # 6; line:  7- 6; sop:  6; eop:  8; out1: 9 
> branch: # 9; line:  6- 6; sop:  9; eop: 10; out1: 11; out2: 6 
> branch: # 11; line:  5- 5; sop: 11; eop: 12; out1: 13 
> branch: # 13; line:  5- 5; sop: 13; eop: 14; out1: 15; out2: 4 
> branch: # 15; line: 10- 10; sop: 15; eop: 19; out1: -2 
> path #1: 0, 13, 15, 
> path #2: 0, 13, 4, 9, 11, 13, 15, 
> path #3: 0, 13, 4, 9, 6, 9, 11, 13, 15, 

Он ($a += $b) просто использует другой, немного медленнее() путь!. Да, медленнее: мои тесты дали 17-е. для $a = $a + $b и 20s. для $a += $b. Не много, хотя и значимо. А также не , что большая разница с JavaScript.

Две минуты для вашей версии PHP достаточно велики, даже старый PHP-5 сделал это за 40 секунд здесь. Я не мог найти ничего в ChangLogs, но вы можете попробовать обновление, если это возможно. Или попробуйте различные оптимизации, если вы скомпилировали его самостоятельно, потому что MAC по-прежнему отличается от «обычного» ПК.