2010-01-15 21 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