Можно ли повторить объект generator
в Python с asyncio
?Я сделал простую функцию с именем hash_generator()
, которая возвращает уникальный хеш.Теперь я решил сравнить цикл и получил около 8 секунд для итерации для печати 100 000 хешей.Могу ли я запустить это в асинхронном режиме, чтобы сократить время?Я прочитал документацию об этом, но я в замешательстве.Я хочу исследовать асинхронность и начать с этой проблемы.
import hashlib
import string
import random
import time
def hash_generator():
"""Return a unique hash"""
prefix = int(time.time())
suffix = (random.choice(string.ascii_letters) for i in range(10))
key = ".".join([str(prefix), str("".join(suffix))])
value = hashlib.blake2b(key.encode(), digest_size=6).hexdigest()
return value.upper()
"""Iterating the hashes and printing the time it loaded"""
hashes = (hash_generator() for i in range(100000))
time_before = time.time()
[print(i) for i in hashes]
time_after = time.time()
difference = time_after - time_before
print('Loaded in {0:.2f}sec'.format(difference))
# 40503CBA2DAE
# ...
# A511068F4945
# Loaded in 8.81sec
РЕДАКТИРОВАНИЕ 1
Функция random.choice()
является основной причиной, по которой программе потребовалось слишком много времени для запуска.Я воссоздаю функцию ниже со текущим временем и случайной строкой из os.urandom
(низкое столкновение) в качестве значений.Я пробовал многопоточность, но вместо того, чтобы выполнять задачу так быстро, она занимает слишком медленно.Любые рекомендации по рефакторингу приведенного ниже кода всегда приветствуются.
import hashlib
import time
import os
import timeit
def hash_generator():
"""Return a unique hash"""
prefix = str(time.time())
suffix = str(os.urandom(10))
key = "".join([prefix, suffix])
value = hashlib.blake2b(key.encode(), digest_size=6).hexdigest()
return value.upper()
"""Iterating the hashes and printing the time it loaded"""
print(timeit.timeit(hash_generator, number=100000), "sec")
# 0.497149389999322 sec
РЕДАКТИРОВАТЬ 2
С помощью Джека Тейлора и Stackoverflowers я могу увидеть разницу, используя multiprocessing
в течение 1M итераций.Я тестирую код ниже.
import hashlib
import time
import os
import timeit
import multiprocessing
def hash_generator(_=None):
"""Return a unique hash"""
prefix = str(time.time())
suffix = str(os.urandom(10))
key = "".join([prefix, suffix])
value = hashlib.blake2b(key.encode(), digest_size=6).hexdigest()
return value.upper()
# Allows for the safe importing of the main module
if __name__ == "__main__":
start_time = time.time()
number_processes = 4
iteration = 10000000
pool = multiprocessing.Pool(number_processes)
results = pool.map(hash_generator, range(iteration))
pool.close()
pool.join()
end_time = time.time()
pool_runtime = end_time - start_time
print('(Pool) Loaded in: {0:.5f} sec'.format(pool_runtime))
ordinary_runtime = timeit.timeit(hash_generator, number=iteration)
print('(Ordinary) Loaded in: {0:.5f} sec'.format(ordinary_runtime))
iteration = 10
(Pool) Loaded in: 1.20685 sec
(Ordinary) Loaded in: 0.00023 sec
iteration = 1000
(Pool) Loaded in: 0.72233 sec
(Ordinary) Loaded in: 0.01767 sec
iteration = 1000
(Pool) Loaded in: 0.99571 sec
(Ordinary) Loaded in: 0.01208 sec
iteration = 10,000
(Pool) Loaded in: 1.07876 sec
(Ordinary) Loaded in: 0.12652 sec
iteration = 100,000
(Pool) Loaded in: 1.57068 sec
(Ordinary) Loaded in: 1.23418 sec
iteration = 1,000,000
(Pool) Loaded in: 4.28724 sec
(Ordinary) Loaded in: 11.56332 sec
iteration = 10,000,000
(Pool) Loaded in: 27.26819 sec
(Ordinary) Loaded in: 132.68170 sec