Matlab, R, Python關於向量化計算和for循環的速度比較?

Matlab和R,有這樣一個特點:向量化運算速度快,但是用for循環速度很慢。

Python有沒有這樣的問題?


向量化運算的話,這些軟體都是通過C/C++,Fortran寫的庫實現的,所以速度差不多。

for循環的話,以我的經驗,安裝原裝語言,不考慮相關庫和編譯優化的情況下,速度從快到慢的排序是MATLAB,Python, R。

MATLAB自R2015b後,循環速度又有大幅度提升。提速的話,考慮mex。mex的編寫與調試不方便(代碼如果有bug,經常MATLAB崩掉),不是萬不得已,我一般不用。

Python主要優勢是它的易用性,需要性能時,可以考慮使用效率高的庫,也可以使用numba,cython,pypy來大幅度提高性能。

R的循環最慢,但是使用它的人,一般不自己寫演算法,一般都是直接調用相關的庫。

以Falccm用的例子為例:

MATLAB的R2016a:

tic;
s = 0;
for k = 1:1e9
s = s + k;
end
toc;
s

結果:

時間已過 3.904714 秒。
s =
5.00000000067109e+17

計算結果有誤差,因為使用的是浮點型。

Python 2.7.11:

import time
from numba import jit

@jit
def testSum():
s = 0
for k in range(1, 1000000001): # 1e9
s += k
return s

t = time.clock()
s = testSum()
print time.clock() - t
print s

結果:

0.023960742777
500000000500000000

計算結果沒有誤差,而且速度更快。

加入numba並不麻煩,僅僅增加了兩行:

from numba import jit
@jit

通過添加變數類型,可以進一步提高性能:

1.3. Compiling Python code with @jit

import time
from numba import jit, int64

@jit(int64())
def testSum():
s = 0
for k in range(1, 1000000001): # 1e9
s += k
return s

t = time.clock()
s = testSum()
print time.clock() - t
print s

結果:

3.01848604067e-06
500000000500000000

測試浮點型運算:

MATLAB R2016a代碼:

tic;
s = 0;
for k = 1:1e9
s = s/3;
s = s + k;
end
toc;
s

結果:

時間已過 9.160245 秒。
s =
1499999999.25

Python 2.7.11:

import time
from numba import jit, float64

@jit(float64())
def testSum():
s = 0.0
for k in range(1, 1000000001): # 1e9
s /= 3.0
s += 1.0 * k
return s

t = time.clock()
s = testSum()
print time.clock() - t
print s

結果:
6.86019338233
1499999999.25

Python+Numba略快。

測試了一下遞歸,MATLAB比Python要快,看來MATLAB在加速,以前的觀念需要更新。

MATLAB R2016a:

function res = fib(n)
if n &< 0 error("n must be non-negative"); end if n &< 2 res = n; return end res = fib(n-1) + fib(n-2); end

tic;disp(fib(35));toc;

結果:

9227465
時間已過 1.597194 秒。

Python 2.7.11:

import time
#from numba import jit
#@jit
def fib(n):
if n &< 0: print "n must be non-negative" return if n &< 2: return n return fib(n - 1) + fib(n - 2) t = time.clock() s = fib(35) print time.clock() - t print s

結果:

3.6433592249
9227465


R 不清楚,不過 MATLAB 目前循環速度已經比原來快很多了:

function testSum
s = 0;
for k = 1:1e9
s = s + k;
end

&>&> tic, testSum; toc
時間已過 4.364448 秒。

雖然很多情況下有比簡單循環更好的寫法,但是至少沒有必要像之前那樣懼怕循環了。可能很多比較經(guo)典(shi)的資料和 MATLAB 版本會讓你對循環性能存在一定誤解

python 的循環反正不快,經常用作 MATLAB 替代的 numpy 也確實有向量化比循環快的情況

試了下 Python:

def testSum():
s = 0
for k in range(1, 100000001): # 1e8
s += k

t = time.clock()
testSum()
print("用時:", time.clock() - t, "秒")

用時: 5.859156802823201 秒

是慢了一點,上邊 python 測試用的是1e8的數據已經比 MATLAB 1e9的慢了

不過參見另一個答案,可以用 Numba 對 python 的循環進行加速,在一些情況下可以達到甚至超過 MATLAB 循環的效果。不過 Numba 適用範圍好像有一定限制,某些情況下可能不如 Python 本身的性能,總之只要使用得當應該是很有利的工具


r是解釋型的,所以for的速度是有瓶頸。

最好的辦法是優化代碼,官網上的task view裡面有很多高效運算包d

matlab py沒學的那麼深入,就不評價了


推薦閱讀:

python中的漢諾塔遞歸演算法的具體運算過程是怎樣的?
Python 里為什麼函數可以返回一個函數內部定義的函數?
為何大量設計模式在動態語言中不適用?
python如何繪製一個橫坐標為字元串,縱坐標為數字的折線圖?
python 的 dict真的不會隨著key的增加而變慢嗎?

TAG:Python | MATLAB | R編程語言 | 量化計算 |