Julia 和 Python,哪一個更快?
Julia 是一門高度抽象的動態編程語言。雖然它是一門能夠開發所有程序的通用語言,但它有幾個特點,非常適用於科學計算和數值計算。Python 在 1990 年初作為一種簡單的面向對象的程序語言出現,如今已經有了顯著的發展。本文將從它們在神經網路和機器學習的性能表現上進行討論。
Julia 的架構以動態語言中的 參數多態性 和 多重派發 的編程範式為主要特色。它允許使用或不使用 消息傳遞介面 (MPI)或內置的 「OpenMP 式」 線程進行並發、並行和分散式計算,以及直接調用 C 和 FORTRAN 庫而無需額外的代碼。Julia 使用 即時 (JIT)編譯器,Julia 社區將其稱為 「 即時預編譯 (JAOT)」,因為它在運行之前默認將所有代碼編譯為機器碼。
與 Python 不同,Julia 是專為統計學和機器學習而設計的。Julia 可以快速的完成線性代數的運算,但 Python 很慢。這是因為 Python 從來都不是為了適應機器學慣用到的矩陣和方程而設計的。Python 本身並不差,特別是 Numpy,但在沒有使用包的情況下,Julia 更像是為數學量身定製的。相比 Python,Julia 的運算符更像 R,這是一個顯著的優勢。大部分的線性代數運算可以用更少的時間和精力去完成。
眾所周知,近年來 Python 在機器學習和數據科學領域佔據主導地位。因為在 Python 中我們可以使用各種各樣的第三方庫來幫助我們編寫機器學習的代碼。雖然 Python 有這麼多優勢,但仍有一個主要的缺點——它是一門解釋性語言,速度非常慢。現在是數據時代,數據越多我們處理它的時間就越長,這也是 Julia 出現的理由。
到目前為止,有關 Julia 的研究工作都集中在高性能或者 Julia 的科學計算能力等主題上。但在這裡,我們將討論 Julia 不僅能夠有效地處理複雜的科學計算,還能夠處理基於商業的問題,以及像 Python 一樣處理機器學習和神經網路。
實驗目標與實驗設計
Julia 像 Python 一樣簡潔,但卻像 C 一樣是一門編譯語言。首先我們來測試 Julia 要比 Python 快多少。為此,我們先在一些簡單的程序上測試它們,然後來到我們實驗的重點,測試它們的機器學習和深度學習能力。
Julia 和 Python 都提供了許多庫和開源的基準測試工具。為了在 Julia 中進行基準測試和計算時間,我們使用了 CPUTime
和 time
庫;對於 Python,我們同樣使用了 time
模塊。
矩陣乘法
一開始我們嘗試了簡單的算術運算,但由於這些運算不會產生太大的時間差異,我們決定比較矩陣乘法的時間差異。我們創建了兩個 (10 * 10)
的隨機浮點數矩陣,並對它們施以點積。眾所周知,Python 有一個 Numpy
庫,常被用於計算矩陣和向量。而 Julia 也有一個 LinearAlgebra
庫,常用於計算矩陣和向量。因此我們分別比較了各自使用和不使用庫的矩陣乘法的耗時。本文用到的所有源碼已經放在了 GitHub 存儲庫。下面給出了用 Julia 編寫的 10×10 矩陣乘法程序:
@time LinearAlgebra.mul!(c,x,y)
function MM()
x = rand(Float64,(10,10))
y = rand(Float64,(10,10))
c = zeros(10,10)
for i in range(1,10)
for j in range(1,10)
for k in range(1,10)
c[i,j] += x[i,k]*y[k,j]
end
end
end
end
@time MM
0.000001 seconds
MM (generic function with 1 method)
Julia 使用庫耗時 0.000017 秒,使用循環耗時 0.000001 秒。
使用 Python 編寫相同的矩陣乘法程序如下。 從結果可以發現,與不使用庫相比,使用庫的程序花費的時間更少:
import numpy as np
import time as t
x = np.random.rand(10,10)
y = np.random.rand(10,10)
start = t.time()
z = np.dot(x, y)
print(「Time = 「,t.time()-start)
Time = 0.001316070556640625
import random
import time as t
l = 0
h= 10
cols = 10
rows= 10
choices = list (map(float, range(l,h)))
x = [random.choices (choices , k=cols) for _ in range(rows)]
y = [random.choices (choices , k=cols) for _ in range(rows)]
result = [([0]*cols) for i in range (rows)]
start = t.time()
for i in range(len(x)):
for j in range(len(y[0])):
for k in range(len(result)):
result[i][j] += x[i][k] * y[k][j]
print(result)
print(「Time = 「, t.time()-start)
Time = 0.0015912055969238281
Python 使用庫耗時 0.0013 秒,使用循環耗時 0.0015 秒。
線性搜索
我們進行的下一個實驗是對十萬個隨機生成的數字進行線性搜索。這裡使用了兩種方法,一種是使用 for
循環,另一種是使用運算符。我們使用 1 到 1000 的整數執行了 1000 次搜索,正如你在下面的輸出中看到的那樣,我們還列印了我們在數據集中找到了多少個整數。下面給出了使用循環和使用 IN
運算符的時間。這裡我們使用了 CPU 3 次運行時間的中位數。
使用 Julia 編寫的程序和運行結果如下:
(LCTT 譯註:此處原文缺失 Julia 代碼)
使用 Python 編寫的程序和運行結果如下:
import numpy as np
import time as t
x = np.random.rand(10,10)
y = np.random.rand(10,10)
start = t.time()
z = np.dot(x, y)
print(「Time = 「,t.time()-start)
Time = 0.001316070556640625
import random
import time as t
l = 0
h= 10
cols = 10
rows= 10
choices = list (map(float, range(l,h)))
x = [random.choices (choices , k=cols) for _ in range(rows)]
y = [random.choices (choices , k=cols) for _ in range(rows)]
result = [([0]*cols) for i in range (rows)]
start = t.time()
for i in range(len(x)):
for j in range(len(y[0])):
for k in range(len(result)):
result[i][j] += x[i][k] * y[k][j]
print(result)
print(「Time = 「, t.time()-start)
Time = 0.0015912055969238281
FOR_SEARCH:
Elapsed CPU time: 16.420260511 seconds
matches: 550
Elapsed CPU time: 16.140975079 seconds
matches: 550
Elapsed CPU time: 16.49639576 seconds
matches: 550
IN:
Elapsed CPU time: 6.446583343 seconds
matches: 550
Elapsed CPU time: 6.216615487 seconds
matches: 550
Elapsed CPU time: 6.296716556 seconds
matches: 550
從以上結果來看,在 Julia 中使用循環和運算符並不會產生顯著的時間差異。但是在 Python 中循環幾乎比運算符 IN 多花了三倍的時間。有趣的是,在這兩種情況下,Julia 都比 Python 快得多。
線性回歸
下一個實驗是測試機器學習演算法。我們選擇了以一種最常見和最簡單的機器學習演算法,使用簡單數據集的線性回歸。我們使用了一個包含 237 條數據的數據集 「Head Brain」,數據集的兩列分別為 「HeadSize」 和 「BrainWeight」。接下來,我們使用 「head size」 數據去計算 「brain weight」。在 Python 和 Julia 中我們都沒有使用第三方庫,而是從零實現了線性回歸演算法。
Julia:
GC.gc()
@CPUtime begin
linear_reg()
end
elapsed CPU time: 0.000718 seconds
Python:
gc.collect()
start = process_time()
linear_reg()
end = process_time()
print(end-start)
elapsed time: 0.007180344000000005
上面給出了 Julia 和 Python 所花費的時間。
邏輯回歸
接下來,我們使用兩種語言的庫對最常見的機器學習演算法(即邏輯回歸)進行了實驗。對於 Python 我們使用最常見的庫 sklearn
;對於 Julia,我們使用 GLM
庫。我們在這裡用到的數據集是有關銀行客戶的信息,其中包含 10,000 個數據條目。目標變數是一個二元變數,區分消費者是否繼續使用銀行賬戶。
下面給出了 Julia 進行邏輯回歸所花費的時間:
@time log_rec()
0.027746 seconds (3.32 k allocations: 10.947 MiB)
下面給出了 Python 進行邏輯回歸所花費的時間:
gc.collect()
start = process_time()
LogReg()
end = process_time()
print(end-start)
Accuracy : 0.8068
0.34901400000000005
神經網路
在各種程序和數據集上測試這兩種語言後,我們在神經網路上使用 MNIST 數據集繼續測試它們。該數據集包含從零到九的手繪數字的灰度圖像。每張圖像為 28×28 像素。每個像素值表示該像素的亮度或暗度,該值是包含 0 到 255 之間的整數。該數據還包含一個標籤列,該列表示在相關圖像中繪製的數字。
圖 1 是 MNIST 數據集的示例。
對兩種語言我們都建立了一個簡單的神經網路來測試它們耗費的時間。神經網路的結構如下:
Input ---> Hidden layer ---> Output
該神經網路包含了一個輸入層、隱層還有輸出層。為了避免神經網路的複雜度過高,我們對數據集沒有進行任何的預處理工作。在 Julia 和 Python 中我們都進行了40次訓練並比較它們的時間差異。
在 Julia 中,Flux
庫通常被用於建立神經網路;在 Python 中我們常使用 Keras
庫。圖 2 展示了 Julia 在神經網路上的耗時。圖 3 展示了 Python 的神經網路經過了若干次訓練的耗時。
這個結果展示了 Julia 和 Python 在處理神經網路時存在巨大的時間差異。
表 1 總結了此次實驗的測試結果並計算了 Julia 和 Python 時間差異的百分比。
實驗 | Julia(秒) | Python(秒) | 時間差(%) |
---|---|---|---|
矩陣乘法(不使用庫) | 0.000001 | 0.0015 | 99.9 |
矩陣乘法(使用庫) | 0.000017 | 0.0013 | 98.69 |
線性搜索(使用循環) | 0.42 | 16.4 | 97.43 |
線性搜索(使用 IN 操作符) | 0.43 | 6.2 | 93.06 |
線性回歸 | 0.000718 | 0.00718 | 90 |
邏輯回歸 | 0.025 | 0.34901 | 92.83 |
神經網路 | 5.76 | 110.3 | 94.77 |
我們進行的所有實驗都表明,隨著程序複雜性以及數據集大小的增加,Julia 和 Python 之間的執行時間差異也會增加。由這個結果我們可以推斷,Julia 是一門更適合機器學習和神經網路的編程語言。
via: https://www.opensourceforu.com/2022/09/julia-and-python-which-language-is-quicker/
作者:B Thangaraju 選題:lkxed 譯者:Return7g 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive