Hemimu
Hemimu

Reputation: 27

Speed up Python script or find alternative?

Here's my current script:

import argparse
from pybitcointools import *

parser = argparse.ArgumentParser()
parser.add_argument('filename')
args = parser.parse_args()

with open(args.filename) as textfile:
    for line in textfile:
       priv = sha256(line.rstrip())
       wif_u = encode_privkey(priv, 'wif')
       wif_c = encode_privkey(priv, 'wif_compressed')
       addr_u = pubtoaddr(privtopub(priv))
       addr_c = pubtoaddr(compress(privtopub(priv)))
       print("%s,%s" % (addr_u, wif_u))
       print("%s,%s" % (addr_c, wif_c))

I run this script to convert 1000 lines into 2000 bitcoin brain wallets (1000 x 2 to include both compressed and uncompressed). It takes 12.5 seconds to run.

If I remove these lines, it goes down from 12.5 seconds to 0.2 seconds:

addr_u = pubtoaddr(privtopub(priv))
addr_c = pubtoaddr(compress(privtopub(priv)))

But of course, I need the addresses, not just the private keys in WIF format.

So here's the 3 things I'm trying to figure out:

  1. Why does address generation take so much longer than private key generation?

  2. Is there a way to speed up the existing Python script to run in less than a second?

  3. If not, does anyone know of a simple alternative that could do this faster?

I don't mind using Python, Perl, C, whatever does the job and is the fastest.

Upvotes: 1

Views: 268

Answers (1)

Dan D.
Dan D.

Reputation: 74645

You are calling privtopub(priv) twice. This would save a call to fast_multiply which is likely the slowest function in this entire program.

I would suggest first doing:

pub = privtopub(priv)
addr_u = pubtoaddr(pub)
addr_c = pubtoaddr(compress(pub))

Then I would suggest using a multiprocessing.Pool:

import argparse
from pybitcointools import *

def convert(line):
    priv = sha256(line.rstrip())
    wif_u = encode_privkey(priv, 'wif')
    wif_c = encode_privkey(priv, 'wif_compressed')
    pub = privtopub(priv)
    addr_u = pubtoaddr(pub)
    addr_c = pubtoaddr(compress(pub))
    return (addr_u, wif_u, addr_c, addr_u)

if __name__=="__main__":

    parser = argparse.ArgumentParser()
    parser.add_argument('filename')
    args = parser.parse_args()

    pool = multiprocessing.Pool()

    with open(args.filename) as textfile:
        for addr_u, wif_u, addr_c, addr_u in pool.imap(convert, textfile):
            print("%s,%s" % (addr_u, wif_u))
            print("%s,%s" % (addr_c, wif_c))

Upvotes: 1

Related Questions