Skip to main content
 首页 » 编程设计

python之Windows 下 python 库 keyczar 的性能

2025年05月04日952php

我正在运行此代码以查看 keyczar encryption library 的性能影响来自谷歌:

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 session :

>>> 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 下载.

请您参考如下方法:

PyCrypto 有一个名为 _fastmath 的 C 模块,它使用 GNU MP 进行公钥操作。如果它不可用,它会使用 Python 的原生长整数,这要慢得多。

这两个文件是src/_fastmath.c和lib/Crypto/PublicKey/_slowmath.py

Windows 上的 Python 可能不包含 GNU MP,因此在 Windows 上它使用 _slowmath.py 代替