Skip to content

Instantly share code, notes, and snippets.

@kylemcdonald
Last active March 13, 2023 21:46
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kylemcdonald/dc3bec51a876c1e6958ab2abc3ba1364 to your computer and use it in GitHub Desktop.
Save kylemcdonald/dc3bec51a876c1e6958ab2abc3ba1364 to your computer and use it in GitHub Desktop.
Python vs Node web3 speed comparison.

Results

+ python get_block_speed_sync_ipc.py
6.2069807052612305
+ python get_block_speed_async_http.py
2.9152305126190186
+ node get_block_speed_sync_ipc.js
2.501
+ python get_block_speed_sync_ipc_raw.py
0.4704411029815674
+ node get_block_speed_async_ipc.js
0.353
#!/bin/bash -x
python get_block_speed_sync_ipc.py
python get_block_speed_async_http.py
node get_block_speed_sync_ipc.js
python get_block_speed_sync_ipc_raw.py
node get_block_speed_async_ipc.js
import time
import asyncio
from web3 import Web3, AsyncHTTPProvider
from web3.eth import AsyncEth
from web3.net import AsyncNet
rpc_node_url = 'http://localhost:8545'
w3_async = Web3(AsyncHTTPProvider(rpc_node_url), modules={'eth': (AsyncEth,), 'net': (AsyncNet,)}, middlewares=[])
async def get_block(block_number):
return await w3_async.eth.get_block(block_number)
async def main():
start = 12965000
end = start + 1000
start_time = time.time()
tasks = [get_block(x) for x in range(start, end)]
task_results = await asyncio.gather(*tasks)
end_time = time.time()
print(end_time - start_time)
asyncio.run(main())
const Web3 = require('web3');
const net = require('net');
const os = require('os');
let ipc = '~/.ethereum/geth.ipc'.replace('~', os.homedir());
let w3 = new Web3(ipc, net);
async function listExtraData() {
const start = 12965000;
const end = start + 1000;
const start_time = Date.now();
let tasks = [];
for (let i = start; i < end; i++) {
tasks.push(w3.eth.getBlock(i));
}
Promise.all(tasks).then((results) => {
const end_time = Date.now();
console.log((end_time - start_time)/1000);
// have to manually exit because IPC can't disconnect
process.exit();
})
}
listExtraData();
const Web3 = require('web3');
const net = require('net');
const os = require('os');
let ipc = '~/.ethereum/geth.ipc'.replace('~', os.homedir());
let w3 = new Web3(ipc, net);
async function listExtraData() {
const start = 12965000;
const end = start + 1000;
const start_time = Date.now();
for (let i = start; i < end; i++) {
const block = await w3.eth.getBlock(i);
}
const end_time = Date.now();
console.log((end_time - start_time)/1000);
}
listExtraData().then(process.exit);
import time
from web3 import Web3
provider = Web3.IPCProvider('~/.ethereum/geth.ipc')
w3 = Web3(provider)
start = 12965000
end = start + 1000
start_time = time.time()
for i in range(start, end):
block = w3.eth.get_block(i)
end_time = time.time()
print(end_time - start_time)
import socket
import os
import itertools
import time
import json
block_number = 12965000
total_blocks = 1000
blocks_per_chunk = 100
ipc_path = '~/.ethereum/geth.ipc'
ipc_path = os.path.expanduser(ipc_path)
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect(ipc_path)
sock.settimeout(0.1)
def receive_response(sock, total):
raw_response = b''
end_chr = ord('\n')
while total > 0:
chunk = sock.recv(1*4096)
raw_response += chunk
total -= chunk.count(b'\n')
return raw_response
start_time = time.time()
request_counter = itertools.count()
responses = b''
for chunk in range(total_blocks//blocks_per_chunk):
for i in range(blocks_per_chunk):
count = next(request_counter)
request = f'{{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["{hex(block_number)}",false],"id":{count}}}'
request = request.encode('ascii')
sock.sendall(request)
block_number += 1
responses += receive_response(sock, blocks_per_chunk)
data = [json.loads(e) for e in responses.split(b'\n')[:-1]]
end_time = time.time()
print(end_time - start_time)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment