2010-01-15 88 views
2

Python庫keyczar的我運行這段代碼,看看從谷歌keyczar encryption library對性能的影響:性能在Windows

from keyczar import keyczar, keys 

def main(iters): 
    key = keys.RsaPrivateKey.Generate() 
    msg = "ciao" 
    crypt = None 
    for i in range(iters): 
     print i, "\r", 
     crypt = key.Encrypt(msg) 
    for i in range(iters): 
     print i, "\r", 
     key.Decrypt(crypt) 

if __name__ == '__main__': 
    main(500) 

在Windows下,500次迭代大約需要16分鐘。在同一臺機器上的Ubuntu 9.04分區下,500次迭代大約需要6秒。

我試着剖析這個(cProfile + pstats),但我沒有太多經驗來解釋結果。

有人能告訴我爲什麼相同的代碼在Windows下運行速度慢150倍以上?


編輯2010-01-16

這裏是我的generate_key.py腳本:

from keyczar import keyczar, keys 

key = keys.RsaPrivateKey.Generate() 

這是我的命令行中generate_key創建一個統計文件:

C:\temp\python-keyczar-0.6b\tests\keyczar>python -m cProfile -o generate_key generate_key.py 

這裏是我的python會話來展開結果:

>>> import pstats 
>>> p = pstats.Stats('generate_key') 
>>> p.strip_dirs().sort_stats(-1).print_stats(25) 
Sat Jan 16 12:18:43 2010 generate_key 

     83493 function calls (82974 primitive calls) in 5.131 CPU seconds 

    Ordered by: standard name 
    List reduced from 564 to 25 due to restriction <25> 

    ncalls tottime percall cumtime percall filename:lineno(function) 
     1 0.000 0.000 0.000 0.000 <string>:1(<module>) 
     1 0.000 0.000 0.210 0.210 AES.py:1(<module>) 
     1 0.022 0.022 0.210 0.210 AES.py:1(__bootstrap__) 
     1 0.000 0.000 0.000 0.000 DSA.py:115(DSAobj) 
     1 0.001 0.001 0.005 0.005 DSA.py:14(<module>) 
     1 0.000 0.000 0.000 0.000 DSA.py:174(DSAobj_c) 
     1 0.000 0.000 0.000 0.000 DSA.py:26(error) 
     1 0.000 0.000 0.001 0.001 RSA.py:125(size) 
     1 0.000 0.000 0.000 0.000 RSA.py:13(<module>) 
     1 0.000 0.000 0.000 0.000 RSA.py:140(publickey) 
     1 0.000 0.000 0.000 0.000 RSA.py:146(RSAobj_c) 
     1 0.000 0.000 0.000 0.000 RSA.py:23(error) 
     1 0.000 0.000 4.816 4.816 RSA.py:26(generate) 
     1 0.000 0.000 0.000 0.000 RSA.py:63(construct) 
     1 0.000 0.000 0.000 0.000 RSA.py:85(RSAobj) 
     1 0.003 0.003 0.004 0.004 SHA.py:4(<module>) 
     1 0.000 0.000 0.000 0.000 __future__.py:48(<module>) 
     1 0.000 0.000 0.000 0.000 __future__.py:74(_Feature) 
     7 0.000 0.000 0.000 0.000 __future__.py:75(__init__) 
     8 0.000 0.000 0.000 0.000 __init__.py:1(<module>) 
     1 0.000 0.000 0.000 0.000 __init__.py:11(<module>) 
     1 0.000 0.000 0.000 0.000 __init__.py:13(<module>) 
     1 0.000 0.000 0.000 0.000 __init__.py:18(<module>) 
     1 0.000 0.000 0.000 0.000 __init__.py:20(<module>) 
     2 0.000 0.000 0.000 0.000 __init__.py:24(<module>) 


<pstats.Stats instance at 0x023F5E40> 
>>> 

所以Windows代碼在Python中執行。大部分的運行時間就是在這裏度過:

def generate(bits, randfunc, progress_func=None): 
    """generate(bits:int, randfunc:callable, progress_func:callable) 

    Generate an RSA key of length 'bits', using 'randfunc' to get 
    random data and 'progress_func', if present, to display 
    the progress of the key generation. 
    """ 
    obj=RSAobj() 

    # Generate the prime factors of n 
    if progress_func: 
     progress_func('p,q\n') 
    p = q = 1L 
    while number.size(p*q) < bits: 
     p = pubkey.getPrime(bits/2, randfunc) 
     q = pubkey.getPrime(bits/2, randfunc) 

    # p shall be smaller than q (for calc of u) 
    if p > q: 
     (p, q)=(q, p) 
    obj.p = p 
    obj.q = q 

    if progress_func: 
     progress_func('u\n') 
    obj.u = pubkey.inverse(obj.p, obj.q) 
    obj.n = obj.p*obj.q 

    obj.e = 65537L 
    if progress_func: 
     progress_func('d\n') 
    obj.d=pubkey.inverse(obj.e, (obj.p-1)*(obj.q-1)) 

    assert bits <= 1+obj.size(), "Generated key is too small" 

    return obj 

我從here運行PyCrypto downloade。

回答

1

PyCrypto有一個名爲_fastmath的C模塊,它將GNU MP用於公鑰操作。如果它不可用,它會使用Python的本地長整數,這比整數要慢得多。

兩個文件是SRC/_fastmath.c和lib /加密/公鑰/ _slowmath.py

這可能是因爲Windows上的Python所以在Windows它,而不是使用_slowmath.py

不包括GNU MP,
+0

這聽起來像是這個問題。 – hughdbrown 2010-01-21 21:15:50

0

對於這種差異,我會懷疑linux正在使用c模塊來工作。也許Windows版本無法在某處安裝dll,因此回退到Python代碼

您是否在兩個平臺上運行相同版本的Python?

+0

我在兩個平臺上都使用2.6.4。你能給我一個關於哪個DLL可能會丟失的想法嗎? – hughdbrown 2010-01-15 22:58:29