2016-09-06 10 views
2

我正在考慮重新實現SlowAES代碼(http://anh.cs.luc.edu/331/code/aes.py)以試圖利用numpy的本地數組支持。對於我來說,我得到的是反直覺的結果,即SlowAES的純Python比使用numpy實現的相同函數要快得多。這是我最清楚的例子。NUMPY AES的實現明顯慢於純python

AES中的一個主要操作是Shift Rows,其中4x4元素字節數組中的每一行都移動了一些位置(0代表0行,1代表1行等)。原始Python代碼把該4×4字節狀態陣列爲一維16元素的列表,然後使用切片來創建虛擬行旋轉:

def rotate(word, n): 
    return word[n:] + word [0:n] 

def shiftRows(state): 
    for i in range(4): 
     state[i*4:i*4+4] = rotate(state[i*4:i*4+4], -i) 

使用在一個時間的16個的整數結果的列表上移位行運行timeit爲3.47微秒。

重新實現在此numpy的相同的功能,假定4×4整數輸入陣列,將是簡單地:

def shiftRows(state): 
    for i in range(4): 
     state[i] = np.roll(state[i],-i) 

然而講,timeit示出了該具有16.3微秒的執行時間。

我希望numpy的優化數組操作可能會導致更快的代碼。我哪裏錯了?是否有一些方法可以比純Python更快地實現AES?我想得到一些中間結果,所以pycrypto可能不適用(但如果這太慢了,我可能不得不再看一次)。

2016年9月07日 - 感謝您的回答。爲了回答「爲什麼」這個問題,我正在運行數十萬甚至數百萬個樣本明文/密文對。所以,雖然任何單一加密的時間差別沒有什麼不同,但我可以節省的任何時間都可以在長期內發揮巨大作用。

+1

「是否有某種方法可以比純Python更快地實現AES?」幾乎可以確定。在C中執行並將綁定導出到Python。不過,我懷疑這不是你要找的答案。 –

+0

'Numpy'通常有更多的「控制」,如果與簡單的「精簡」來源相比,它會減慢它的速度。在這裏檢查'roll'的sourse代碼:https://github.com/numpy/numpy/blob/v1.11.0/numpy/core/numeric.py#L1335-L1401 – RafazZ

+0

3.5 vs 16微秒?這個問題是否會擴大到你可能會說話10秒或幾分鐘?我在這裏看不到什麼大問題,除非這是針對優化清酒問題的優化。 – 2016-09-06 20:30:47

回答

1

簡單的答案是,創建數組有很多開銷。因此小列表上的操作通常比數組上的等價操作更快。如果數組版本像列表一樣迭代,那就更是如此。對於大型數組,使用編譯方法的操作將更快。

這4個 '滾' 定時說明這

對於一個小清單:

In [93]: timeit x=list(range(16)); x=x[8:]+x[:8] 
100000 loops, best of 3: 2.75 µs per loop 
In [94]: timeit y=np.arange(16); y=np.roll(y,8) 
The slowest run took 40.90 times longer than the fastest. This could mean that an intermediate result is being cached. 
100000 loops, best of 3: 14.5 µs per loop 

了很大的一個:

In [95]: timeit x=list(range(1000)); x=x[500:]+x[:500] 
10000 loops, best of 3: 52.9 µs per loop 
In [96]: timeit y=np.arange(1000); y=np.roll(y,500) 
The slowest run took 28.91 times longer than the fastest. This could mean that an intermediate result is being cached. 
10000 loops, best of 3: 22.2 µs per loop 

我們可以進一步通過提取range細化問題和arange逐步退出定時循環。

np.roll操作基本上:

y[np.concatenate((np.arange(8,16), np.arange(0,8)))] 

即構建體4個陣列中,2 arange,所述concatenate,和最終索引數組。