Найти - Пользователи
Полная версия: Многороточность при конвертации
Начало » Python для новичков » Многороточность при конвертации
1 2
nv_fan
Здравствуйте.
Имеется скрипт выполняющий конвертацию HEX значений в конечный адрес по заданному алгоритму.

 import base58
from ripemd160 import ripemd160
from sha256 import sha256
class PublicKey:
    p_curve = (2**256 - 2**32 - 2**9 - 2**8 - 2**7 - 2**6 - 2**4 - 1)
    n_curve = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 
    a_curve, b_curve = 0, 7
    gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240
    gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424
    gpoint = (gx, gy)
    def __init__(self, private_key):
        self.private_key = private_key
    @property
    def private_key(self):
        return self.__private_key
    @private_key.setter
    def private_key(self, key):
        try:
            key = int(str(key), 16)
        except ValueError:
            raise NotImplementedError('Private key must be a hexadecimal number')
        if key <= 0 or key >= self.n_curve:
            raise Exception("Invalid Scalar/Private Key")
        self.__private_key = key
    def __modinv(self, a, n):
        lm, hm = 1, 0
        low, high = a % n, n
        while low > 1:
            ratio = int(high/low)
            nm, new = int(hm-lm*ratio), int(high-low*ratio)
            lm, low, hm, high = nm, new, lm, low
        return lm % n
    def __ec_add(self, a, b):
        lam_add = ((b[1]-a[1]) * self.__modinv(b[0] - a[0], self.p_curve)) % self.p_curve
        x = (pow(lam_add, 2)-a[0]-b[0]) % self.p_curve
        y = (lam_add*(a[0]-x)-a[1]) % self.p_curve
        return x, y
    def __ec_double(self, a):
        lam = ((3*a[0]*a[0]+self.a_curve) * self.__modinv((2*a[1]), self.p_curve)) % self.p_curve
        x = int((lam*lam-2*a[0]) % self.p_curve)
        y = int((lam*(a[0]-x)-a[1]) % self.p_curve)
        return x, y
    def __ec_multiply(self, genpoint, scalarhex):
        scalarbin = str(bin(scalarhex))[2:]
        q = genpoint
        for i in range(1, len(scalarbin)):
            q = self.__ec_double(q)
            if scalarbin[i] == "1":
                q = self.__ec_add(q, genpoint)
        return q
    def __compute_public(self):
        return self.__ec_multiply(self.gpoint, self.private_key)
    def __public_address(self, key):
        key = bytes.fromhex(key)
        address = bytes.fromhex(f"00{ripemd160(sha256(key)).hex()}")
        checksum = sha256(sha256(address))
        address = f"{address.hex()}{checksum.hex()[:8]}"
        address = base58.b58encode(bytes.fromhex(address)).decode("UTF-8")
        return address
    def write_public_keys(self):
        public_key = self.__compute_public()
        uncomp_pub = f"04{public_key[0]:0>64x}{public_key[1]:0>64x}"
        uncomp_addr = self.__public_address(uncomp_pub)
        arq1.write(f"Secret: {prompt}\n")
        arq1.write(f"-----------------------------------------------------------------\n")
        arq1.write(f"Uncompressed: {uncomp_addr}\n")
        arq2.write(f"{uncomp_addr}\n")
        if public_key[1] % 2 == 1:
            comp_pub = f"03{public_key[0]:0>64x}"
        else:
            comp_pub = f"02{public_key[0]:0>64x}"
        comp_addr = self.__public_address(comp_pub)
        arq1.write(f"Compressed: {comp_addr}\n")
        arq2.write(f"{comp_addr}\n")
        arq1.write(f"-----------------------------------------------------------------\n")
with open("input.txt") as file:
    for line in file:
        arq1 = open('result.txt', 'a')
        arq2 = open('output.txt', 'a')
        prompt = str.strip(line)
        my_key = PublicKey(prompt)
        my_key.write_public_keys()
arq1.close()
arq2.close()

Скрипт полностью рабочий и алгоритм конвертации производит верные расчеты, но крайне медленно.
На обработку 300к строк уходит ~86 мин.
Помогите прикрутить многопоточность.
Rodegast
> На обработку 300к строк уходит ~86 мин. Помогите прикрутить многопоточность.

Не поможет тебе многопоточность.
nv_fan
Rodegast
> Не поможет тебе многопоточность.

Я правильно понимаю что единственный вариант ускорить процесс - это смотреть в сторону GPU ?
Rodegast
Я бы для начала посмотрел в сторону cython | numba | pypy
nv_fan
Rodegast
Я бы для начала посмотрел в сторону cython | numba | pypy

pypy - пробовал, там прирост скорости всего в 1.5 раза. Посмотрим что остальные покажут.
Спасибо.
xam1816
Интересно, будет ли прирост если код
nv_fan
with open(“input.txt”) as file:
for line in file:
arq1 = open('result.txt', ‘a’)
arq2 = open('output.txt', ‘a’)
заменить на
 with open("input.txt") as file:
        with open('result.txt', 'a') as arq1, open('output.txt', 'a') as arq2:
            for line in file:

вот здесь
  
arq1.write(f"Secret: {prompt}\n")
        arq1.write(f"-----------------------------------------------------------------\n")
        arq1.write(f"Uncompressed: {uncomp_addr}\n")
        arq2.write(f"{uncomp_addr}\n")
        if public_key[1] % 2 == 1:
            comp_pub = f"03{public_key[0]:0>64x}"
        else:
            comp_pub = f"02{public_key[0]:0>64x}"
        comp_addr = self.__public_address(comp_pub)
        arq1.write(f"Compressed: {comp_addr}\n")
        arq2.write(f"{comp_addr}\n")
        arq1.write(f"-----------------------------------------------------------------\n")

если сначала подготовить строку и потом один раз вызвать метод write

Rodegast
> Интересно, будет ли прирост если код…

Будет, но не то что бы сильный. Скорее всего у него идёт упор в процессор. Если бы было несколько тяжёлых вычислений, а не много маленьких, то можно было бы попробовать распараллелить их через multiprocessing.

Идеальный вариант это разбить входной файл на части и запустить несколько скриптов вывод которых потом объединить, но не знаю насколько это возможно с точки зрения бизнеспроцессов.
ZerG
Тут очень много действий с I/O
Я бы предложил создать массив в памяти - то есть считать все данные в память - потом обработать все что нужно после чего разово пихнуть уже в файл на диск
Тут же все упирается пока что в чтение записи

А уже потом можно смотреть в мультипроцессинг
py.user.next
nv_fan
Помогите прикрутить многопоточность.
Сначала надо разделить ввод, вычисления и вывод на отдельные части. Сейчас это всё перемешано.

Потом надо вычисления, часть вычислений, измерить по времени. Надо узнать, сколько времени вычисляются 300000 входных наборов данных.

Если они вычисляются довольно медленно, можно разбить входные наборы данных на части (с 1 по 100000, с 100001 по 200000, с 200001 по 300000) и запустить для каждой части отдельный процесс вычислений этой части. Три процесса одновременно запустить, каждый из которых вычисляет свою часть.

Дальше можно сделать три параллельных процесса. Один процесс вводит данные из файла, другой процесс вычисляет данные, третий процесс выводит данные в файл. И дальше можно сделать несколько процессов в процессе вычисления данных. Один процесс вычисляет первую часть, второй процесс вычисляет вторую часть, третий процесс вычисляет третью часть. Частей данных может быть и больше - десять, двадцать и так далее.

Так ты можешь распараллеливать любые части выполнения алгоритма.

nv_fan
Я правильно понимаю что единственный вариант ускорить процесс - это смотреть в сторону GPU ?
Не, можно ещё вычисляющую часть алгоритма написать в виде отдельной программы на другом языке программирования.

Просто твой перемешанный код как раз и мешает что-либо делать. Это как пытаться найти иголку в стоге сена или в куче сваленных в одно место абсолютно разных и неупорядоченных вещей пытаться найти конкретную.

Я вот когда хочу чай попить, я беру кружку. Знаешь, где я её беру? Я беру её там, где у меня лежат кружки все и стаканы - там, где у меня находится класс питьевых ёмкостей, если по-нашему выразиться. Я знаю, что кружка лежит там где-то, а не в сарае, где свалены в одну кучу лодки, сети, сломанные телевизоры, шубы, маслёнки, санки, ацетон и кастрюли с крышками и другие неизвестные и давно забытые предметы.

Если у тебя код сделан в виде свалки, то ты даже замерить вычисления не можешь, потому что к ним подмешаны вводы из файлов и выводы в файлы. Сначала это всё надо убрать и разложить по своим местам, а уже потом в это углубляться и сконцентрированно анализировать.

Лучше выбирать кружку среди кружек и стаканов, а не среди всякого хлама, который не в тему.
beatrice09
Многоточность (или многозначность) в контексте перевода или конвертации текста относится к ситуации, когда один и тот же источник текста может быть интерпретирован или переведен несколькими способами.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB