2013-06-21 3 views
5

Я бегу питона 2.7 и MATLAB R2010a на той же машине, ничего не делая, и это дает мне 10x разные скоростицикл в питона 10x медленнее, чем MATLAB

Я посмотрел в Интернете, и услышал это должно быть то же самое заказ. Python будет продолжать замедляться, как оператор оператора и оператора математики в цикле for

Мой вопрос: это реальность? или есть какой-то другой способ позволить им в том же порядке скорости?


Вот кода Python

import time 

start_time = time.time() 

for r in xrange(1000): 

     for c in xrange(1000): 

     continue 

elapsed_time = time.time() - start_time 

print 'time cost = ',elapsed_time 

Output: time cost = 0.0377440452576

Вот MATLAB кодовая

tic 

for i = 1:1000 

    for j = 1:1000 

    end 

end 

toc 

Output: Escaped time is 0.004200 seconds

+0

Я не слишком, если есть любая разница с оптимизатором компилятора, но вы попробовали пройти вместо продолжения? Возможно, если вы добавите очень простой расчет, 't = t + 1', то он изменится. – slbass

+0

Тестирование цикла с помощью 'python -m timeit' показывает, что использование' pass' немного медленнее, чем 'continue', но не в значительной степени. На моей машине петли занимают 16 мсек, что меньше половины того, что утверждает ОП. Также обратите внимание, что MATLAB имеет [JIT] (http://www.matlabtips.com/matlab-is-no-longer-slow-at-for-loops/), поэтому такие различия следует ожидать * особенно * с помощью простых петли. – Bakuriu

+3

Возможно, стоит положить что-то внутри цикла, на всякий случай Matlab достаточно умен, чтобы понять, что петли фактически ничего не делают и оптимизировали их. – Aya

ответ

2

Если Python execut производительность ионов действительно важно для вас, вы можете взглянуть на PyPy

Я сделал ваш тест:

import time 
for a in range(10): 
    start_time = time.time() 
    for r in xrange(1000): 
     for c in xrange(1000): 
      continue 

    elapsed_time = time.time()-start_time 
    print elapsed_time 

со стандартным Python 2.7.3, я получаю:

0.0311839580536 
0.0310959815979 
0.0309510231018 
0.0306520462036 
0.0302460193634 
0.0324130058289 
0.0308878421783 
0.0307397842407 
0.0304911136627 
0.0307500362396 

тогда, используя PyPy 1.9.0 (что соответствует Python 2.7.2), я получаю:

0.00921821594238 
0.0115230083466 
0.00851202011108 
0.00808095932007 
0.00496387481689 
0.00499391555786 
0.00508499145508 
0.00618195533752 
0.005126953125 
0.00482988357544 

Ускорение o f PyPy действительно потрясающий и действительно становится видимым, когда его оптимизация компилятора JIT перевешивает их стоимость. Вот почему я представил дополнительный цикл. Для этого примера абсолютно не требуется модификация кода.

+3

Проблема с PyPy заключается в том, что она по-прежнему не поддерживает NumPy, поэтому это не идеальная замена MATLAB. –

8

Причина, по которой это происходит, связана с компилятором JIT, который оптимизирует цикл MATLAB for. Вы можете отключить/включить ускоритель JIT с помощью feature accel off и feature accel on. Когда вы отключите акселератор, времена резко меняются.

MATLAB с Accel на: Elapsed time is 0.009407 seconds.

MATLAB с разгона от: Elapsed time is 0.287955 seconds.

питон: time cost = 0.0511920452118

Таким образом, JIT ускоритель непосредственно вызывает ускорение, что вы замечаете. Есть еще одна вещь, которую вы должны рассмотреть, что связано с тем, как вы определили итерационные индексы. В обоих случаях, MATLAB и python, вы использовали Итераторы для определения ваших циклов. В MATLAB вы создаете фактические значения, добавляя квадратные скобки ([]), а в python вы используете range вместо xrange.Когда вы делаете эти изменения

% MATLAB 
for i = [1:1000] 
    for j = [1:1000] 

# python 
for r in range(1000): 
    for c in range(1000): 

Времена становятся

MATLAB с Accel на: Elapsed time is 0.338701 seconds.

MATLAB с Accel офф: Elapsed time is 0.289220 seconds.

питон: time cost = 0.0606048107147

Одно последнее соображение если бы вы добавили быстрый цикл в цикл. т.е. t=t+1. Тогда времена становятся

MATLAB с Accel на: Elapsed time is 1.340830 seconds.

MATLAB с Accel выкл: Elapsed time is 0.905956 seconds. (да прочь был быстрее)

питон: time cost = 0.147221088409

Я думаю, что мораль состоит в том, что скорости вычислений для петель, из коробки, сопоставимы для чрезвычайно простых циклов, в зависимости от ситуации. Тем не менее, в python есть другие, численные инструменты, которые могут значительно ускорить процесс, numpy и PyPy были доведены до сих пор.

+0

Python 'xrange' - простой итератор. Если вы хотите сравнить версию MATLAB с python, вы должны использовать простой «диапазон». – Bakuriu

+0

@Bakuriu Вы правы, я поменял свое сообщение на использование диапазона и обновил среду выполнения, хотя ничего не изменилось. – slbass

+0

Какие результаты вы получите, если сравниваете одни и те же блоки кода, но используя 'Matlab' для i = 1: 1000' против Python 2.x' xrange'? – Aya

3

Основная реализация Python, CPython, не должна быть сверхскоростной. Если вам нужна эффективная численная манипуляция в стиле Matlab, используйте the numpy package или реализацию Python, предназначенную для быстрой работы, например PyPy или даже Cython. (Написание расширения Python на C, которое, конечно, будет довольно быстрым, также является возможным решением, но в этом случае вы можете просто использовать numpy и сэкономить усилия.)