⚡️ Speed up method digifinex.parse_transfer by 22%
#37
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
📄 22% (0.22x) speedup for
digifinex.parse_transferinpython/ccxt/digifinex.py⏱️ Runtime :
1.07 milliseconds→873 microseconds(best of62runs)📝 Explanation and details
The optimized code achieves a 22% speedup through several key micro-optimizations that reduce function call overhead and eliminate redundant operations in hot path methods:
Key Optimizations Applied:
safe_string inlining: Replaced the
Exchange.key_exists()method call with direct type checking and dictionary/list access. This eliminates one function call per invocation and reduces the time from 1756ns to 314ns per hit - a 82% improvement for this critical utility function.safe_integer streamlining: Combined key existence checking with value retrieval in a single operation, reducing multiple dictionary lookups. The optimization shows a 35% improvement in per-hit time (2042ns → 1230ns).
iso8601 format optimization: Pre-computed timestamp conversion and consolidated string formatting operations. Instead of multiple string concatenations and formatting calls, the optimized version uses a single
.format()call, reducing the expensive string operations from 13684ns to 10266ns per hit.safe_dict direct implementation: Eliminated the method indirection to
safe_dict_n()by implementing the logic directly, reducing the total time from 3287ns to 234ns per hit - a 93% improvement.parse_transfer local caching: Introduced intermediate variables to cache repeated method call results, particularly for currency string processing and status parsing, avoiding redundant
safe_stringcalls.Performance Impact:
The optimizations are particularly effective for the test cases shown, with improvements ranging from 18-33% across different scenarios. The largest gains occur in simpler cases (empty transfers, missing fields) where the overhead reduction is most pronounced. Complex transfers with nested data structures see more modest but consistent 20-25% improvements.
Why This Matters:
Since these are utility functions in a cryptocurrency exchange library, they're likely called frequently during market data processing, order parsing, and API response handling - making even small per-call optimizations compound into significant performance gains in high-throughput scenarios.
✅ Correctness verification report:
🌀 Generated Regression Tests and Runtime
import copy
imports
import pytest
from ccxt.digifinex import digifinex
---- UNIT TESTS ----
@pytest.fixture
def dfex():
# Provide a fresh digifinex instance for each test
return digifinex()
----------- BASIC TEST CASES ------------
def test_basic_spot_to_swap(dfex):
# Typical transfer from spot to swap
transfer = {
"transfer_id": "12345",
"type": 1,
"currency": "usdt",
"amount": "24.5",
"timestamp": 1666505659000,
"code": 0
}
codeflash_output = dfex.parse_transfer(transfer); result = codeflash_output # 33.6μs -> 27.9μs (20.7% faster)
def test_basic_swap_to_spot(dfex):
# Typical transfer from swap to spot
transfer = {
"transfer_id": "54321",
"type": 2,
"currency": "BTC",
"amount": "1.234",
"timestamp": 1666505659001,
"code": 0
}
codeflash_output = dfex.parse_transfer(transfer); result = codeflash_output # 33.1μs -> 27.5μs (20.3% faster)
def test_basic_otc_transfer(dfex):
# Transfer with only code, no data (spot/margin/otc)
transfer = {
"code": 0
}
codeflash_output = dfex.parse_transfer(transfer); result = codeflash_output # 15.5μs -> 11.7μs (31.9% faster)
def test_basic_data_field(dfex):
# Transfer with 'data' field (spot <-> swap)
transfer = {
"code": 0,
"data": {
"type": 2,
"currency": "USDT",
"transfer_amount": "5"
}
}
codeflash_output = dfex.parse_transfer(transfer); result = codeflash_output # 18.3μs -> 14.5μs (26.6% faster)
def test_basic_fetch_transfers(dfex):
# Transfer from fetchTransfers endpoint
transfer = {
"transfer_id": 130524,
"type": 1,
"currency": "USDT",
"amount": "24",
"timestamp": 1666505659000
}
codeflash_output = dfex.parse_transfer(transfer); result = codeflash_output # 33.7μs -> 27.8μs (21.1% faster)
----------- EDGE TEST CASES ------------
def test_edge_missing_type(dfex):
# Transfer missing 'type' field
transfer = {
"transfer_id": "99999",
"currency": "ETH",
"amount": "0.123",
"timestamp": 1666505659002,
"code": 0
}
codeflash_output = dfex.parse_transfer(transfer); result = codeflash_output # 33.7μs -> 27.1μs (24.4% faster)
def test_edge_missing_currency(dfex):
# Transfer missing 'currency'
transfer = {
"transfer_id": "88888",
"type": 1,
"amount": "10",
"timestamp": 1666505659003,
"code": 0
}
codeflash_output = dfex.parse_transfer(transfer); result = codeflash_output # 31.7μs -> 26.3μs (20.4% faster)
def test_edge_missing_amount(dfex):
# Transfer missing 'amount' and 'transfer_amount'
transfer = {
"transfer_id": "77777",
"type": 2,
"currency": "USDT",
"timestamp": 1666505659004,
"code": 0
}
codeflash_output = dfex.parse_transfer(transfer); result = codeflash_output # 33.0μs -> 26.5μs (24.6% faster)
def test_edge_missing_timestamp(dfex):
# Transfer missing 'timestamp'
transfer = {
"transfer_id": "66666",
"type": 1,
"currency": "USDT",
"amount": "100",
"code": 0
}
codeflash_output = dfex.parse_transfer(transfer); result = codeflash_output # 17.6μs -> 14.3μs (22.9% faster)
def test_edge_null_values(dfex):
# Transfer with None values
transfer = {
"transfer_id": None,
"type": None,
"currency": None,
"amount": None,
"timestamp": None,
"code": None
}
codeflash_output = dfex.parse_transfer(transfer); result = codeflash_output # 14.2μs -> 11.5μs (23.3% faster)
def test_edge_type_as_string(dfex):
# 'type' as string instead of int
transfer = {
"transfer_id": "55555",
"type": "1",
"currency": "USDT",
"amount": "1.5",
"timestamp": 1666505659005,
"code": 0
}
codeflash_output = dfex.parse_transfer(transfer); result = codeflash_output # 34.1μs -> 27.9μs (21.9% faster)
def test_edge_amount_as_int(dfex):
# 'amount' as int instead of string
transfer = {
"transfer_id": "44444",
"type": 2,
"currency": "USDT",
"amount": 7,
"timestamp": 1666505659006,
"code": 0
}
codeflash_output = dfex.parse_transfer(transfer); result = codeflash_output # 33.3μs -> 27.8μs (19.7% faster)
def test_edge_transfer_amount_field(dfex):
# Only 'transfer_amount' present
transfer = {
"transfer_id": "33333",
"type": 2,
"currency": "USDT",
"transfer_amount": "9.99",
"timestamp": 1666505659007,
"code": 0
}
codeflash_output = dfex.parse_transfer(transfer); result = codeflash_output # 33.4μs -> 27.4μs (21.9% faster)
def test_edge_data_overrides(dfex):
# Both top-level and data fields present, data should override
transfer = {
"transfer_id": "22222",
"type": 1,
"currency": "USDT",
"amount": "10",
"timestamp": 1666505659008,
"code": 0,
"data": {
"type": 2,
"currency": "BTC",
"transfer_amount": "1.5"
}
}
codeflash_output = dfex.parse_transfer(transfer); result = codeflash_output # 33.6μs -> 27.6μs (21.8% faster)
def test_edge_status_nonzero(dfex):
# 'code' not 0, should return code as status
transfer = {
"transfer_id": "11111",
"type": 1,
"currency": "USDT",
"amount": "5",
"timestamp": 1666505659009,
"code": 1
}
codeflash_output = dfex.parse_transfer(transfer); result = codeflash_output # 32.5μs -> 26.8μs (21.5% faster)
def test_edge_currency_case(dfex):
# Lowercase, mixed case currency
transfer = {
"transfer_id": "10101",
"type": 1,
"currency": "eTh",
"amount": "2",
"timestamp": 1666505659010,
"code": 0
}
codeflash_output = dfex.parse_transfer(transfer); result = codeflash_output # 32.6μs -> 27.0μs (20.9% faster)
def test_edge_large_timestamp(dfex):
# Very large timestamp
transfer = {
"transfer_id": "20202",
"type": 1,
"currency": "USDT",
"amount": "1",
"timestamp": 9999999999999,
"code": 0
}
codeflash_output = dfex.parse_transfer(transfer); result = codeflash_output # 32.5μs -> 27.2μs (19.4% faster)
def test_edge_negative_timestamp(dfex):
# Negative timestamp should yield None for datetime
transfer = {
"transfer_id": "30303",
"type": 1,
"currency": "USDT",
"amount": "1",
"timestamp": -1000,
"code": 0
}
codeflash_output = dfex.parse_transfer(transfer); result = codeflash_output # 17.6μs -> 14.4μs (22.4% faster)
def test_edge_empty_transfer(dfex):
# Completely empty dict
transfer = {}
codeflash_output = dfex.parse_transfer(transfer); result = codeflash_output # 15.0μs -> 11.5μs (30.6% faster)
----------- LARGE SCALE TEST CASES ------------
def test_large_scale_all_fields(dfex):
# All fields present and 'data' field for each
transfers = []
for i in range(100):
transfers.append({
"transfer_id": str(i),
"type": 1,
"currency": "BTC",
"amount": str(i),
"timestamp": 1666505659000 + i,
"code": 0,
"data": {
"type": 2,
"currency": "USDT",
"transfer_amount": str(i * 2)
}
})
results = [dfex.parse_transfer(t) for t in transfers]
# All should parse as swap->spot, currency USDT, amount i*2
for i, res in enumerate(results):
pass
def test_large_scale_varied_codes(dfex):
# Many transfers with varied code/status
transfers = []
for i in range(100):
transfers.append({
"transfer_id": str(i),
"type": 1,
"currency": "BTC",
"amount": str(i),
"timestamp": 1666505659000 + i,
"code": str(i % 3)
})
results = [dfex.parse_transfer(t) for t in transfers]
for i, res in enumerate(results):
expected_status = "ok" if str(i % 3) == "0" else str(i % 3)
def test_large_scale_data_field_only(dfex):
# Transfers with only 'data' field, no top-level fields
transfers = []
for i in range(100):
transfers.append({
"data": {
"type": 1 if i % 2 == 0 else 2,
"currency": "BTC" if i % 3 == 0 else "USDT",
"amount": str(i)
}
})
results = [dfex.parse_transfer(t) for t in transfers]
for i, res in enumerate(results):
if i % 2 == 0:
pass
else:
pass
expected_currency = "BTC" if i % 3 == 0 else "USDT"
codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
#------------------------------------------------
import pytest
from ccxt.digifinex import digifinex
Fixtures for reusability
@pytest.fixture
def parser():
return digifinex()
----------------- Basic Test Cases -----------------
def test_basic_spot_to_swap(parser):
# Typical transfer from spot to swap
transfer = {
"transfer_id": 12345,
"type": 1,
"currency": "USDT",
"amount": "100.50",
"timestamp": 1680000000000,
"code": "0"
}
codeflash_output = parser.parse_transfer(transfer); result = codeflash_output # 35.1μs -> 28.8μs (22.0% faster)
def test_basic_swap_to_spot(parser):
# Typical transfer from swap to spot, with nested data
transfer = {
"code": 0,
"data": {
"type": 2,
"currency": "BTC",
"transfer_amount": "0.005"
}
}
codeflash_output = parser.parse_transfer(transfer); result = codeflash_output # 18.5μs -> 14.5μs (27.6% faster)
def test_basic_otc_transfer(parser):
# Transfer between spot, margin, OTC (no type field)
transfer = {
"code": 0
}
codeflash_output = parser.parse_transfer(transfer); result = codeflash_output # 15.8μs -> 12.1μs (30.4% faster)
def test_basic_fetch_transfers(parser):
# Transfer from fetchTransfers endpoint
transfer = {
"transfer_id": 130524,
"type": 1,
"currency": "USDT",
"amount": "24",
"timestamp": 1666505659000
}
codeflash_output = parser.parse_transfer(transfer); result = codeflash_output # 34.2μs -> 28.2μs (21.3% faster)
----------------- Edge Test Cases -----------------
def test_edge_missing_type(parser):
# No type field, should not set from/toAccount
transfer = {
"transfer_id": 999,
"currency": "ETH",
"amount": "1.23",
"timestamp": 1600000000000,
"code": "0"
}
codeflash_output = parser.parse_transfer(transfer); result = codeflash_output # 32.9μs -> 27.3μs (20.6% faster)
def test_edge_missing_currency(parser):
# No currency field
transfer = {
"transfer_id": 999,
"type": 2,
"amount": "1.23",
"timestamp": 1600000000000,
"code": "0"
}
codeflash_output = parser.parse_transfer(transfer); result = codeflash_output # 31.6μs -> 26.0μs (21.4% faster)
def test_edge_missing_amount(parser):
# No amount or transfer_amount field
transfer = {
"transfer_id": 888,
"type": 1,
"currency": "USDT",
"timestamp": 1600000000000,
"code": "0"
}
codeflash_output = parser.parse_transfer(transfer); result = codeflash_output # 32.7μs -> 27.0μs (21.4% faster)
def test_edge_amount_is_not_number(parser):
# Amount is not a number
transfer = {
"transfer_id": 777,
"type": 1,
"currency": "USDT",
"amount": "not_a_number",
"timestamp": 1600000000000,
"code": "0"
}
codeflash_output = parser.parse_transfer(transfer); result = codeflash_output # 34.2μs -> 28.7μs (19.1% faster)
def test_edge_currency_is_common_code(parser):
# Currency is a common code (XBT -> BTC)
transfer = {
"transfer_id": 555,
"type": 1,
"currency": "XBT",
"amount": "0.01",
"timestamp": 1600000000000,
"code": "0"
}
codeflash_output = parser.parse_transfer(transfer); result = codeflash_output # 32.3μs -> 27.3μs (18.3% faster)
def test_edge_code_not_ok(parser):
# Status code is not '0'
transfer = {
"transfer_id": 444,
"type": 1,
"currency": "USDT",
"amount": "10",
"timestamp": 1600000000000,
"code": "1"
}
codeflash_output = parser.parse_transfer(transfer); result = codeflash_output # 32.6μs -> 27.4μs (19.1% faster)
def test_edge_negative_timestamp(parser):
# Negative timestamp
transfer = {
"transfer_id": 333,
"type": 1,
"currency": "USDT",
"amount": "10",
"timestamp": -1000,
"code": "0"
}
codeflash_output = parser.parse_transfer(transfer); result = codeflash_output # 17.4μs -> 14.6μs (18.8% faster)
def test_edge_missing_transfer_id(parser):
# No transfer_id field
transfer = {
"type": 1,
"currency": "USDT",
"amount": "10",
"timestamp": 1600000000000,
"code": "0"
}
codeflash_output = parser.parse_transfer(transfer); result = codeflash_output # 32.8μs -> 27.6μs (18.9% faster)
def test_edge_nested_data_missing_fields(parser):
# Nested data, missing currency and transfer_amount
transfer = {
"code": 0,
"data": {
"type": 2
}
}
codeflash_output = parser.parse_transfer(transfer); result = codeflash_output # 16.3μs -> 12.5μs (30.8% faster)
def test_edge_type_not_1_or_2(parser):
# Type is not 1 or 2
transfer = {
"transfer_id": 222,
"type": 3,
"currency": "USDT",
"amount": "10",
"timestamp": 1600000000000,
"code": "0"
}
codeflash_output = parser.parse_transfer(transfer); result = codeflash_output # 33.3μs -> 27.6μs (20.4% faster)
def test_edge_amount_is_zero(parser):
# Amount is zero
transfer = {
"transfer_id": 111,
"type": 1,
"currency": "USDT",
"amount": "0",
"timestamp": 1600000000000,
"code": "0"
}
codeflash_output = parser.parse_transfer(transfer); result = codeflash_output # 32.9μs -> 27.3μs (20.5% faster)
def test_edge_currency_lowercase(parser):
# Currency in lowercase
transfer = {
"transfer_id": 101,
"type": 1,
"currency": "usdt",
"amount": "10",
"timestamp": 1600000000000,
"code": "0"
}
codeflash_output = parser.parse_transfer(transfer); result = codeflash_output # 33.1μs -> 27.4μs (20.4% faster)
def test_edge_missing_all_fields(parser):
# Completely empty dict
transfer = {}
codeflash_output = parser.parse_transfer(transfer); result = codeflash_output # 14.5μs -> 10.9μs (32.6% faster)
----------------- Large Scale Test Cases -----------------
def test_large_scale_nested_data(parser):
# Test parsing 300 transfers with nested data dicts
transfers = []
for i in range(300):
t = {
"code": 0,
"data": {
"type": 2 if i % 2 == 0 else 1,
"currency": "USDT" if i % 3 == 0 else "BTC",
"transfer_amount": str(i * 0.01)
}
}
transfers.append(t)
results = [parser.parse_transfer(t) for t in transfers] # 20.0μs -> 15.6μs (28.7% faster)
for i, r in enumerate(results):
if transfers[i]["data"]["type"] == 2:
pass
else:
pass
def test_large_scale_performance(parser):
# Test performance for 900 transfers
import time
transfers = []
for i in range(900):
t = {
"transfer_id": i,
"type": 1,
"currency": "USDT",
"amount": str(i),
"timestamp": 1600000000000 + i * 1000,
"code": "0"
}
transfers.append(t)
start = time.time()
results = [parser.parse_transfer(t) for t in transfers] # 37.3μs -> 30.0μs (24.2% faster)
end = time.time()
for i, r in enumerate(results):
pass
codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
To edit these changes
git checkout codeflash/optimize-digifinex.parse_transfer-mhu3eyr7and push.