Adds a paired benchmark of informix-db (pure Python) against IfxPy 3.0.5 (IBM's C-bound driver via OneDB ODBC) on identical workloads against the same Informix dev container. Headline result: pure Python is competitive — and faster on 2/5 benchmarks where wire round-trip dominates over codec/marshaling. | Benchmark | IfxPy | informix-db | Result | |---|---:|---:|---:| | select_one_row (single-row latency) | 128 us | 116 us | us 9% faster | | select_systables_first_10 | 126 us | 184 us | IfxPy 32% faster | | select_bench_table_all (1k rows) | 969 us | 855 us | us 12% faster | | executemany(1000) in txn | 21.5 ms | 30.8 ms | IfxPy 30% slower | | cold_connect_disconnect | 11.0 ms | 10.9 ms | comparable | Why the surprising wins: IfxPy's path is Python -> OneDB ODBC -> libifdmr -> wire. Ours is Python -> wire. When wire round-trip dominates (single-row, bulk fetch), the missing abstraction layer makes us faster. When per-row marshaling dominates (executemany), IfxPy's C-level execute(stmt, tuple) beats Python BIND-PDU build. Files added under tests/benchmarks/compare/: * Dockerfile.ifxpy — Ubuntu 20.04 base with IfxPy + OneDB drivers * ifxpy_bench.py — IfxPy benchmark workloads matching test_*_perf.py * README.md — methodology, results, install gauntlet, reproduction The IfxPy install gauntlet itself is part of the comparison story: modern Python 3.11 (not 3.13), setuptools <58, permissive CFLAGS, manual download of 92MB OneDB ODBC tarball, four LD_LIBRARY_PATH directories, libcrypt.so.1 (deprecated 2018, missing on Arch / Fedora 35+ / RHEL 9). Versus our `pip install informix-db`. README.md (project root): added "Compared to IfxPy" section under Performance with the headline numbers and a pointer to the full methodology. .gitignore: keep Dockerfile/script/README under tests/benchmarks/ compare/, exclude the 92MB OneDB tarball and the local venv.
67 lines
1.2 KiB
Plaintext
67 lines
1.2 KiB
Plaintext
# Project-private context (per global CLAUDE.md rule: only add to private repos)
|
|
CLAUDE.md
|
|
|
|
# Python
|
|
__pycache__/
|
|
*.py[cod]
|
|
*$py.class
|
|
*.so
|
|
.Python
|
|
build/
|
|
dist/
|
|
*.egg-info/
|
|
.eggs/
|
|
.installed.cfg
|
|
*.egg
|
|
|
|
# Virtual environments
|
|
.venv/
|
|
venv/
|
|
env/
|
|
.env
|
|
.env.*
|
|
!.env.example
|
|
|
|
# uv
|
|
.python-version
|
|
|
|
# IDE / editor
|
|
.vscode/
|
|
.idea/
|
|
*.swp
|
|
*.swo
|
|
*~
|
|
|
|
# Test / lint caches
|
|
.pytest_cache/
|
|
.ruff_cache/
|
|
.mypy_cache/
|
|
.coverage
|
|
.coverage.*
|
|
htmlcov/
|
|
|
|
# OS
|
|
.DS_Store
|
|
Thumbs.db
|
|
|
|
# Phase 0 build artifacts (decompiled JDBC, downloaded JARs)
|
|
# build/ already excluded by Python pattern above; we keep the directory for spike work
|
|
build/jdbc-src/
|
|
build/*.jar
|
|
|
|
# Wireshark / socat captures live IN the repo intentionally — they're spike deliverables.
|
|
# The global ~/.gitignore_global excludes *.log; negate that for our captures specifically:
|
|
!docs/CAPTURES/
|
|
!docs/CAPTURES/*.log
|
|
!docs/CAPTURES/*.pcap
|
|
!docs/CAPTURES/*.txt
|
|
|
|
# Java reference client build outputs
|
|
*.class
|
|
tests/benchmarks/.results/
|
|
# IfxPy comparison: keep Dockerfile, bench script, README;
|
|
# exclude the downloaded ODBC driver tarball and local venv.
|
|
tests/benchmarks/compare/venv-py311/
|
|
tests/benchmarks/compare/onedb/
|
|
tests/benchmarks/compare/onedb.tar
|