Как заменить встроенный метод Python вместо установленного стороннего модуля? - PullRequest
0 голосов
/ 11 июля 2019

Я оптимизирую свой код и заменил встроенный в Python hashlib.pbkdf2_hmac на 40% быстрее Быстрая реализация PBKDF2 python-fastpbkdf2 .

Однако при использовании cProfile результат выглядит одинаково.

Я (пытался) убедиться, что я использую модуль Fast PBKDF2 вместо встроенного модуля hashlib.pbkdf2_hmac, но не могу понять, почему я не вижу повышения производительности на 40%.

from fastpbkdf2 import pbkdf2_hmac

phrase_words = "clerk great coin mistake become"
passphrase = 'passphrase'

seed = pbkdf2_hmac('sha512', bytes(complete_phrase_words, encoding='utf-8'), bytes('mnemonic' + passphrase, encoding='utf-8'), 2048)

Как мне убедиться, что я не использую метод build in?

Отчет cProfile:

186811385 function calls (186811349 primitive calls) in 885.041 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   109344  710.505    0.006  710.505    0.006 {built-in method _fastpbkdf2.fastpbkdf2_hmac_sha512}
 57919431   54.060    0.000   54.060    0.000 {built-in method builtins.format}
 57918564   45.288    0.000  116.547    0.000 crypto_awesomer_fast_pbkdf2_test.py:75(<genexpr>)
  3619696   20.854    0.000  137.401    0.000 {method 'join' of 'str' objects}
 57919431   20.604    0.000   20.604    0.000 {method 'zfill' of 'str' objects}
  1755108   14.666    0.000  877.752    0.001 crypto_awesomer_fast_pbkdf2_test.py:66(validate)
  1755108    4.119    0.000    4.119    0.000 {method 'to_bytes' of 'int' objects}
  1755108    3.949    0.000    3.949    0.000 {method 'digest' of '_hashlib.HASH' objects}
        1    3.825    3.825  884.982  884.982 crypto_awesomer_fast_pbkdf2_test.py:33(nested_loops)
  1755109    2.859    0.000    2.859    0.000 {built-in method _hashlib.openssl_sha256}
   109344    1.937    0.000  714.213    0.007 crypto_awesomer_fast_pbkdf2_test.py:89(generate_seed)
   109344    1.315    0.000  712.156    0.007 __init__.py:18(pbkdf2_hmac)


1 Ответ

2 голосов
/ 11 июля 2019

Вы использовали модуль Fast PBKDF2, как показывает вывод cProfile.

Я предполагаю, что любые измерения производительности, выполненные python-fastpbkdf2, сравнивались со старыми версиями Python, OpenSSL или обоими,и более новые версии набрали скорость (в то время как Fast PBKDF2 не обновлялся более трех лет).Похоже, что по состоянию на 2016 год (через год после того, как Fast PBKDF2 увидел свое последнее обновление), Python добавил быстрый путь при связывании с OpenSSL 1.1.0 или выше, который использует оптимизированные OpenSSL PKCS5_PBKDF2_HMACчем доморощенная (более медленная) версия Python.И даже до этого, Python улучшил свою доморощенную версию еще в конце 2013 года ;если бы тесты python-fastpbkdf2 были выполнены до того, как это улучшение было выпущено, производительность была бы намного хуже.

По сути, не предполагайте, что утверждения о том, что они на 40% быстрее, верны, даже если они были верны впрошлое (и нет гарантии, что они были правдой и в прошлом).

Возможно также, что компиляторы и / или ваши сопровождающие репозитория пакетов создали лучшие версии OpenSSL;по крайней мере одно из заявленных преимуществ Fast PBKDF2 заключается в том, что он явно указывал ряд операций, но правильно скомпилированная версия OpenSSL, использующая PGO + LTO, в любом случае сможет автоматически встроить соответствующие операции (и если файлы установки для python-fastpbkdf2 неправильно скомпилировал его с PGO + LTO, в результате он мог проиграть).Между этим и OpenSSL, делающим подобные улучшения кода, разрыв легко мог бы сузиться.

...