diff --git a/.github/workflows/cpp.yml b/.github/workflows/cpp.yml deleted file mode 100644 index 3c54f85..0000000 --- a/.github/workflows/cpp.yml +++ /dev/null @@ -1,94 +0,0 @@ -name: Benchmark C++ version - -on: - push: - branches: - - add_cpp_benchmark - -jobs: - benchmark: - runs-on: ubuntu-latest - - services: - postgres: - image: postgres:latest - env: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: postgres - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 5432:5432 - - steps: - - name: Checkout repository and submodules - uses: actions/checkout@v2 - with: - submodules: recursive - - name: Set up CMake and Conan - uses: actions/setup-python@v2 - with: - python-version: '3.x' - - name: Install utilities - run: | - sudo apt update - sudo apt install -y cmake build-essential - pip install conan - - name: Set up Conan dependencies - run: | - conan profile detect - echo " - [settings] - arch=x86_64 - build_type=Release - compiler=gcc - compiler.cppstd=gnu20 - compiler.libcxx=libstdc++11 - compiler.version=11 - os=Linux - " > ~/.conan2/profiles/default - conan profile show - - name: Install dependencies - run: | - git clone https://github.com/linksplatform/conan-center-index - cd conan-center-index && cd recipes - conan create platform.interfaces/all --version 0.3.41 - conan create platform.delegates/all --version 0.3.7 - conan create platform.exceptions/all --version 0.3.2 - conan create platform.converters/all --version 0.2.0 - conan create platform.hashing/all --version 0.5.6 --build=missing - conan create platform.ranges/all --version 0.2.0 - conan create platform.random/all --version 0.2.0 - conan create platform.equality/all --version 0.0.1 - conan create platform.collections/all --version 0.2.1 - conan create platform.setters/all --version 0.1.0 - conan create platform.data/all --version 0.1.1 - conan create platform.numbers/all --version 0.1.0 - conan create platform.memory/all --version 0.1.0 --build=missing - conan create platform.collections.methods/all --version 0.3.0 - conan create platform.data.doublets/all --version 0.1.0 - - name: Build benchmark - run: | - cd cpp - conan install . -of=build --build=missing - cmake -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=/home/runner/work/Comparisons.PostgreSQLVSDoublets/Comparisons.PostgreSQLVSDoublets/cpp/build/conan_toolchain.cmake -DCMAKE_POLICY_DEFAULT_CMP0091=NEW -DCMAKE_BUILD_TYPE=Release -S . -B build - cd build - make - - name: Run benchmark - run: ./cpp/build/bin/PSQLBench --benchmark_out=cpp/out.txt --benchmark_out_format=console - - name: Prepare benchmark results - run: | - cd cpp - pip install numpy matplotlib - python3 out.py - - name: Save benchmark results - uses: actions/upload-artifact@v4 - with: - name: Benchmark results - path: | - cpp/Bench1.png - cpp/Bench2.png diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index da511e6..61c790d 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -1,132 +1,191 @@ -name: Benchmark Rust version +name: Test and benchmark Rust and C# on: push: - branches: - - main - - master + branches: [main, master] + paths: ['rust/**', 'csharp/**', 'scripts/**', 'experiments/**', 'rust-toolchain.toml', 'rustfmt.toml', '.github/workflows/rust.yml'] pull_request: - branches: - - main - - master + branches: [main, master] + paths: ['rust/**', 'csharp/**', 'scripts/**', 'experiments/**', 'rust-toolchain.toml', 'rustfmt.toml', '.github/workflows/rust.yml'] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: benchmarks-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} env: - toolchain: stable - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + POSTGRES_CONNECTION: 'host=localhost port=5432 user=postgres password=postgres dbname=postgres' + NPGSQL_CONNECTION: 'Host=localhost;Port=5432;Username=postgres;Password=postgres;Database=postgres' + POSTGRES_VERSION: '17.6' jobs: - benchmark: + sizes: runs-on: ubuntu-latest + timeout-minutes: 5 + outputs: + background: ${{ steps.matrix.outputs.background }} + steps: + - id: matrix + env: + EVENT: ${{ github.event_name }} + run: | + if [ "$EVENT" = pull_request ]; then + echo 'background=[100]' >> "$GITHUB_OUTPUT" + else + echo 'background=[100,1000]' >> "$GITHUB_OUTPUT" + fi + test: + runs-on: ubuntu-latest + timeout-minutes: 15 services: postgres: - image: postgres:latest + image: postgres:17.6 env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: postgres - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 5432:5432 - + options: --health-cmd pg_isready --health-interval 5s --health-timeout 5s --health-retries 10 + ports: ['5432:5432'] steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Rust - uses: dtolnay/rust-toolchain@master + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable with: - toolchain: ${{env.toolchain}} components: rustfmt, clippy + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + - run: python3 -m unittest discover -s scripts -v + - run: python3 experiments/reproduce_report_ratio.py + - run: cargo fmt --manifest-path rust/Cargo.toml -- --check + - run: cargo clippy --locked --manifest-path rust/Cargo.toml --all-targets --all-features -- -D warnings + - run: cargo test --locked --manifest-path rust/Cargo.toml -- --include-ignored + + test-csharp: + runs-on: ubuntu-latest + timeout-minutes: 15 + services: + postgres: + image: postgres:17.6 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres + options: --health-cmd pg_isready --health-interval 5s --health-timeout 5s --health-retries 10 + ports: ['5432:5432'] + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: '10.0.x' + - run: dotnet restore csharp/PostgreSQLVSDoublets.slnx --locked-mode + - run: dotnet format csharp/PostgreSQLVSDoublets.slnx --verify-no-changes --no-restore + - run: dotnet build csharp/PostgreSQLVSDoublets.slnx -c Release --no-restore --warnaserror + - run: dotnet test csharp/PostgreSQLVSDoublets.slnx -c Release --no-build --blame-hang-timeout 2m - - name: Wait for PostgreSQL to be ready - run: | - echo "Waiting for PostgreSQL to be fully ready..." - for i in {1..30}; do - if pg_isready -h localhost -p 5432 -U postgres > /dev/null 2>&1; then - echo "PostgreSQL is ready!" - break - fi - echo "Attempt $i: PostgreSQL not ready yet..." - sleep 2 - done - - - name: Build benchmark - run: cargo build --release --all-features --manifest-path rust/Cargo.toml - - - name: Run benchmark - working-directory: rust + benchmark: + needs: [sizes, test, test-csharp] + runs-on: ubuntu-latest + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + language: [rust, csharp] + backend: [psql, doublets] + background: ${{ fromJSON(needs.sizes.outputs.background) }} + services: + postgres: + image: ${{ matrix.backend == 'psql' && 'postgres:17.6' || '' }} env: - POSTGRES_HOST: localhost - POSTGRES_PORT: 5432 POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: postgres - # Use 100 links for main/master branch benchmarks, 10 for pull requests - BENCHMARK_LINKS: ${{ (github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')) && '100' || '10' }} - # Use 1000 background links for main/master branch, 100 for pull requests - BENCHMARK_BACKGROUND_LINKS: ${{ (github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')) && '1000' || '100' }} + options: --health-cmd pg_isready --health-interval 5s --health-timeout 5s --health-retries 10 + ports: ['5432:5432'] + env: + BENCHMARK_BACKEND: ${{ matrix.backend }} + BENCHMARK_BACKGROUND_LINKS: ${{ matrix.background }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + - uses: dtolnay/rust-toolchain@stable + if: matrix.language == 'rust' + - uses: actions/setup-dotnet@v4 + if: matrix.language == 'csharp' + with: + dotnet-version: '10.0.x' + - name: Build benchmark before measuring + env: + LANGUAGE: ${{ matrix.language }} run: | - set -o pipefail - cargo bench --bench bench -- --output-format bencher | tee out.txt - - - name: Prepare benchmark results - if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') + if [ "$LANGUAGE" = rust ]; then + cargo bench --locked --manifest-path rust/Cargo.toml --bench bench --no-run + else + dotnet restore csharp/PostgreSQLVSDoublets/PostgreSQLVSDoublets.csproj --locked-mode + dotnet build csharp/PostgreSQLVSDoublets/PostgreSQLVSDoublets.csproj -c Release --no-restore --warnaserror + fi + - name: Measure one backend and size + env: + LANGUAGE: ${{ matrix.language }} run: | - git config --global user.email "linksplatform@gmail.com" - git config --global user.name "LinksPlatformBencher" - cd rust - pip install numpy matplotlib - python3 out.py - cd .. - - # Create Docs directory if it doesn't exist - mkdir -p Docs - - # Copy generated images - cp -f rust/bench_rust.png Docs/ - cp -f rust/bench_rust_log_scale.png Docs/ - - # Update README with latest results - if [ -f rust/results.md ]; then - # Replace the results section in README.md - python3 -c " - import re - - with open('rust/results.md', 'r') as f: - results = f.read() - - with open('README.md', 'r') as f: - readme = f.read() - - # Pattern to find and replace the results table - pattern = r'(\| Operation.*?\n\|[-|]+\n(?:\|.*?\n)*)' - if re.search(pattern, readme): - readme = re.sub(pattern, results.strip() + '\n', readme) - - with open('README.md', 'w') as f: - f.write(readme) - " + set -o pipefail + export BENCHMARK_LINKS=$((BENCHMARK_BACKGROUND_LINKS / 10)) + mkdir -p results + output="results/$LANGUAGE-$BENCHMARK_BACKGROUND_LINKS-$BENCHMARK_BACKEND.txt" + if [ "$BENCHMARK_BACKEND" = psql ]; then + export POSTGRES_VERSION=$(psql "$POSTGRES_CONNECTION" -Atc 'SHOW server_version') fi - - # Commit changes if any - git add Docs README.md - if git diff --staged --quiet; then - echo "No changes to commit" + python3 scripts/benchmark_header.py "$LANGUAGE" "$BENCHMARK_BACKEND" > "$output" + if [ "$LANGUAGE" = rust ]; then + (cd rust && cargo bench --locked --bench bench -- --output-format bencher --noplot) | tee -a "$output" else - git commit -m "Update benchmark results" - git push origin HEAD + dotnet run --project csharp/PostgreSQLVSDoublets -c Release --no-build | tee -a "$output" fi + - uses: actions/upload-artifact@v4 + with: + name: results-${{ matrix.language }}-${{ matrix.background }}-${{ matrix.backend }} + path: results/*.txt + if-no-files-found: error - - name: Save benchmark results - uses: actions/upload-artifact@v4 + report: + needs: benchmark + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + - uses: actions/download-artifact@v4 with: - name: Benchmark results + pattern: results-* + path: results + merge-multiple: true + - run: python3 -m pip install -r scripts/requirements.txt + - name: Generate tables and charts + run: python3 scripts/benchmark_report.py results --readme README.md --charts Docs > results/report.md + - uses: actions/upload-artifact@v4 + with: + name: benchmark-report path: | - rust/bench_rust.png - rust/bench_rust_log_scale.png - rust/out.txt + README.md + Docs/bench_*.png + results/ + - name: Publish results on the default branch + if: github.event_name == 'push' + run: | + git config user.email 'linksplatform@gmail.com' + git config user.name 'LinksPlatformBencher' + git add README.md Docs + if ! git diff --staged --quiet; then + git commit -m 'Update Rust and C# benchmark results' + git pull --rebase origin "$GITHUB_REF_NAME" + git push origin "HEAD:$GITHUB_REF_NAME" + fi diff --git a/.gitignore b/.gitignore index 90f7c20..3f25c8e 100644 --- a/.gitignore +++ b/.gitignore @@ -370,3 +370,8 @@ MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ + +# Benchmark output and integration-test evidence +*.links +results/ +ci-logs/ diff --git a/Docs/bench_csharp_100.png b/Docs/bench_csharp_100.png new file mode 100644 index 0000000..36b3e55 Binary files /dev/null and b/Docs/bench_csharp_100.png differ diff --git a/Docs/bench_csharp_log_scale_100.png b/Docs/bench_csharp_log_scale_100.png new file mode 100644 index 0000000..3880f27 Binary files /dev/null and b/Docs/bench_csharp_log_scale_100.png differ diff --git a/Docs/bench_rust_100.png b/Docs/bench_rust_100.png new file mode 100644 index 0000000..09851e2 Binary files /dev/null and b/Docs/bench_rust_100.png differ diff --git a/Docs/bench_rust_log_scale_100.png b/Docs/bench_rust_log_scale_100.png new file mode 100644 index 0000000..1dbc548 Binary files /dev/null and b/Docs/bench_rust_log_scale_100.png differ diff --git a/README.md b/README.md index 6ecd8f4..c50d893 100644 --- a/README.md +++ b/README.md @@ -1,48 +1,126 @@ # Comparisons.PostgreSQLVSDoublets -The comparison between PostgreSQL and LinksPlatform's Doublets (links) on basic database operations with links (create, read, delete, update). -All benchmarks ran with 3000 links in background to increase size of indexes and 1000 are actively created/updated/deleted. +PostgreSQL and LinksPlatform Doublets compared on the same basic link operations in Rust and C#. A doublet link has an ID, a source and a target. See [the links theory](https://habr.com/ru/articles/895896) for the representation. -In this particular benchmark we decided not to increase the number of links as PostgreSQL will not be able to handle it at all in timeframe what GitHub Actions limit allows to use for free. Remember that to get accurate result we ran this benchmark multiple times. +Each language runs four Doublets stores (united/split, in RAM/memory-mapped files) and two PostgreSQL modes (autocommit/explicit transaction). PostgreSQL uses a `bigint` identity primary key and separate B-tree indexes on source and target. Doublets runs inside the benchmark process; PostgreSQL uses a local server and includes driver and network costs. Memory-mapped Doublets writes use the OS page cache without an explicit disk flush; their durability differs from PostgreSQL commits. -## Task +## Operations -Both databases used to store and retrieve doublet-links representation. To support storage, and all basic CRUD operations that provide Turing completeness for links as in [the links theory](https://habr.com/ru/articles/895896). +- **Create**: create `BENCHMARK_LINKS` point links (`id = source = target`). +- **Update**: change the last `BENCHMARK_LINKS` background points to `(0, 0)` and back, timing both updates. +- **Delete**: prepare `BENCHMARK_LINKS` additional points, then delete those points in reverse order. +- **Each All**: enumerate all background links once (`[*, *, *]`). +- **Each Identity**: enumerate `[id, *, *]` for each background point. +- **Each Concrete**: enumerate `[*, source, target]` for each background point. +- **Each Outgoing**: enumerate `[*, source, *]` for each background point. +- **Each Incoming**: enumerate `[*, *, target]` for each background point. -## Operations -- **Create** – insert point link (link with id = source = target) -- **Update** – basic link update operation -- **Delete** – basic link delete operation -- **Each All** – take all links matching `[*, *, *]` constraint -- **Each Incoming** – take all links matching `[*, *, target]` constraint -- **Each Outgoing** – take all links matching `[*, source, *]` constraint -- **Each Concrete** – take all links matching `[*, source, target]` constraint -- **Each Identity** – take all links matching `[id, *, *]` constraint +Both languages recreate `BENCHMARK_BACKGROUND_LINKS` points before each iteration and clear the store afterwards. Background creation, delete preparation, table/index setup and cleanup are excluded from the measured time. In transaction mode the timed SQL operations run inside an explicit transaction; its begin and commit happen outside the timed interval. Thus these numbers measure operation batches, rather than committed transactions or individual links. Indexed reads perform one query per background point, independently of `BENCHMARK_LINKS`. + +Both harnesses use one second of warm-up, ten flat samples and a one-second measurement target. Iteration counts are calibrated using total wall time including preparation, as Criterion 0.4 does for `iter_custom`; reported samples include only timed operations. The report shows medians and compares each Doublets median with the fastest PostgreSQL median. Medians within 5%, or overlapping ± one standard deviation ranges, are labelled `≈ same`. Other cells show `× faster` or `× slower`. Linear charts give very short bars a minimum visible width; log charts use the measured values. ## Results -The results below represent the amount of time (ns) the operation takes per iteration. -- First picture shows time in a pixel scale (for doublets just minimum value is shown, otherwise it will be not present on the graph). -- Second picture shows time in a logarithmic scale (to see difference clearly, because it is around 2-3 orders of magnitude). + +Every generated table records the server and library versions, CPU, UTC date and source Actions run. CI runs on separate runners for each language, backend and size. PRs use 100 background / 10 active links. Default-branch runs also measure 1,000 background / 100 active links. A report job assembles all tables and linear/log charts, uploads them for PR review, and commits results after default-branch pushes. Changes only to this README or the charts do not start benchmarks. + + + ### Rust -![Image of Rust benchmark (pixel scale)](https://github.com/linksplatform/Comparisons.PostgreSQLVSDoublets/blob/main/Docs/bench_rust.png?raw=true) -![Image of Rust benchmark (log scale)](https://github.com/linksplatform/Comparisons.PostgreSQLVSDoublets/blob/main/Docs/bench_rust_log_scale.png?raw=true) -### Raw benchmark results (all numbers are in nanoseconds) +#### Rust: 100 background links, 10 links per iteration + +_Median time of one iteration with 10 links. PostgreSQL 17.6 (Debian 17.6-2.pgdg13+1) through postgres 0.19.7; doublets 0.3.0. CPU AMD EPYC 7763 64-Core Processor (PostgreSQL) and AMD EPYC 9V45 96-Core Processor (Doublets), [GitHub Actions run](https://github.com/linksplatform/Comparisons.PostgreSQLVSDoublets/actions/runs/37548090422) on 2026-10-06T23:46:07+00:00._ + +| Operation | Doublets United Volatile | Doublets United NonVolatile | Doublets Split Volatile | Doublets Split NonVolatile | PostgreSQL NonTransaction | PostgreSQL Transaction | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | +| Create | 514 ns (21,300× faster) | 512 ns (21,400× faster) | 421 ns (26,000× faster) | 416 ns (26,300× faster) | 13.8 ms | **10.9 ms** | +| Update | 1.69 µs (8,440× faster) | 1.62 µs (8,760× faster) | 583 ns (24,400× faster) | 583 ns (24,400× faster) | 17.5 ms | **14.2 ms** | +| Delete | 729 ns (5,000× faster) | 736 ns (4,960× faster) | 771 ns (4,730× faster) | 796 ns (4,580× faster) | 5.02 ms | **3.65 ms** | +| Each All | 36 ns (10,300× faster) | 35 ns (10,600× faster) | 143 ns (2,600× faster) | 142 ns (2,620× faster) | 390 µs | **371 µs** | +| Each Identity | 2.42 µs (14,600× faster) | 2.39 µs (14,800× faster) | 2.44 µs (14,500× faster) | 2.44 µs (14,500× faster) | 36.5 ms | **35.4 ms** | +| Each Concrete | 2.85 µs (12,800× faster) | 2.83 µs (12,900× faster) | 3.12 µs (11,700× faster) | 3.13 µs (11,700× faster) | 37.7 ms | **36.6 ms** | +| Each Outgoing | 3.39 µs (10,400× faster) | 3.34 µs (10,600× faster) | 2.72 µs (13,000× faster) | 2.73 µs (13,000× faster) | 36.3 ms | **35.4 ms** | +| Each Incoming | 3.42 µs (10,400× faster) | 3.37 µs (10,600× faster) | 2.76 µs (12,900× faster) | 2.75 µs (13,000× faster) | 36.9 ms | **35.6 ms** | + +![Rust, 100 background links, 10 links per iteration, linear scale](Docs/bench_rust_100.png) +![Rust, 100 background links, 10 links per iteration, log scale](Docs/bench_rust_log_scale_100.png) + +### C# + +#### C#: 100 background links, 10 links per iteration + +_Median time of one iteration with 10 links. PostgreSQL 17.6 (Debian 17.6-2.pgdg13+1) through Npgsql 10.0.0; Platform.Data.Doublets 0.18.1. CPU AMD EPYC 7763 64-Core Processor (PostgreSQL) and Intel(R) Xeon(R) 6973P-C (Doublets), [GitHub Actions run](https://github.com/linksplatform/Comparisons.PostgreSQLVSDoublets/actions/runs/37548090422) on 2026-10-06T23:45:47+00:00._ + +| Operation | Doublets United Volatile | Doublets United NonVolatile | Doublets Split Volatile | Doublets Split NonVolatile | PostgreSQL NonTransaction | PostgreSQL Transaction | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | +| Create | 2.79 µs (2,600× faster) | 2.87 µs (2,530× faster) | 418 ns (17,400× faster) | 1.24 µs (5,830× faster) | 9.85 ms | **7.26 ms** | +| Update | 3.39 µs (2,920× faster) | 3.39 µs (2,920× faster) | 235 ns (42,100× faster) | 223 ns (44,400× faster) | 12.4 ms | **9.9 ms** | +| Delete | 1.33 µs (1,860× faster) | 1.41 µs (1,760× faster) | 525 ns (4,710× faster) | 1.17 µs (2,110× faster) | 3.66 ms | **2.47 ms** | +| Each All | 1.13 µs (245× faster) | 1.12 µs (248× faster) | 906 ns (306× faster) | 908 ns (305× faster) | **277 µs** | 284 µs | +| Each Identity | 606 ns (39,500× faster) | 619 ns (38,700× faster) | 815 ns (29,400× faster) | 789 ns (30,400× faster) | 24.4 ms | **24 ms** | +| Each Concrete | 705 ns (36,000× faster) | 842 ns (30,100× faster) | 763 ns (33,300× faster) | 756 ns (33,600× faster) | 25.8 ms | **25.4 ms** | +| Each Outgoing | 1.08 µs (22,300× faster) | 1.12 µs (21,500× faster) | 911 ns (26,500× faster) | 977 ns (24,700× faster) | 24.9 ms | **24.1 ms** | +| Each Incoming | 2.1 µs (11,500× faster) | 2.21 µs (11,000× faster) | 844 ns (28,800× faster) | 840 ns (28,900× faster) | 24.7 ms | **24.3 ms** | + +![C#, 100 background links, 10 links per iteration, linear scale](Docs/bench_csharp_100.png) +![C#, 100 background links, 10 links per iteration, log scale](Docs/bench_csharp_log_scale_100.png) + + + + +Results depend on workload, server configuration, versions and runner hardware. Use the provenance and sizes above each table when comparing runs. + +## Running locally + +Install stable Rust, .NET 10, Python 3.11+ and PostgreSQL. The CI server image is pinned to `postgres:17.6`. Use a disposable database: the benchmarks create and drop a table named `links`, and correctness tests reset that table. + +```bash +docker run -d --name comparison-postgres -p 5432:5432 \ + -e POSTGRES_PASSWORD=postgres postgres:17.6 +export POSTGRES_CONNECTION='host=localhost port=5432 user=postgres password=postgres dbname=postgres' +export NPGSQL_CONNECTION='Host=localhost;Port=5432;Username=postgres;Password=postgres;Database=postgres' +export POSTGRES_VERSION=17.6 +export BENCHMARK_BACKGROUND_LINKS=100 +export BENCHMARK_LINKS=10 +python3 -m pip install -r scripts/requirements.txt + +# Report regressions and backend correctness. +python3 -m unittest discover -s scripts -v +cargo fmt --manifest-path rust/Cargo.toml -- --check +cargo clippy --locked --manifest-path rust/Cargo.toml --all-targets --all-features -- -D warnings +cargo test --locked --manifest-path rust/Cargo.toml -- --include-ignored +dotnet restore csharp/PostgreSQLVSDoublets.slnx --locked-mode +dotnet format csharp/PostgreSQLVSDoublets.slnx --verify-no-changes --no-restore +dotnet build csharp/PostgreSQLVSDoublets.slnx -c Release --no-restore --warnaserror +dotnet test csharp/PostgreSQLVSDoublets.slnx -c Release --no-build --blame-hang-timeout 2m -| Operation | Doublets United Volatile | Doublets United NonVolatile | Doublets Split Volatile | Doublets Split NonVolatile | PSQL NonTransaction | PSQL Transaction | -|---------------|--------------------------|-----------------------------|-------------------------|----------------------------|---------------------|------------------| -| Create | 9035 (12162.4x faster) | 8807 (12477.2x faster) | 7005 (15686.9x faster) | 7086 (15507.6x faster) | 145975967 | 109886881 | -| Update | 33210 (4323.7x faster) | 32724 (4387.9x faster) | 7826 (18347.9x faster) | 7756 (18513.5x faster) | 181785688 | 143590948 | -| Delete | 17427 (2096.8x faster) | 17237 (2119.9x faster) | 12612 (2897.4x faster) | 12659 (2886.6x faster) | 54113187 | 36541411 | -| Each All | 1903 (394.1x faster) | 1903 (394.1x faster) | 2520 (297.6x faster) | 2220 (337.8x faster) | 772260 | 750025 | -| Each Identity | 32364 (10720.2x faster) | 32376 (10716.2x faster) | 32675 (10618.2x faster) | 32678 (10617.2x faster) | 365907001 | 346948519 | -| Each Concrete | 47228 (7710.2x faster) | 46435 (7841.9x faster) | 42978 (8472.6x faster) | 43041 (8460.2x faster) | 388005509 | 364137549 | -| Each Outgoing | 60270 (5830.3x faster) | 59978 (5858.7x faster) | 36132 (9725.2x faster) | 36206 (9705.3x faster) | 369609106 | 351390605 | -| Each Incoming | 59812 (5849.0x faster) | 59956 (5835.0x faster) | 36733 (9523.9x faster) | 36753 (9518.7x faster) | 362811363 | 349842592 | +# Run backends sequentially to avoid CPU contention. +mkdir -p results +for language in rust csharp; do + for backend in psql doublets; do + export BENCHMARK_BACKEND="$backend" + output="results/$language-$BENCHMARK_BACKGROUND_LINKS-$backend.txt" + python3 scripts/benchmark_header.py "$language" "$backend" > "$output" + if [ "$language" = rust ]; then + (cd rust && cargo bench --locked --bench bench -- --output-format bencher --noplot) >> "$output" + else + dotnet run --project csharp/PostgreSQLVSDoublets -c Release --no-build >> "$output" + fi + done +done +python3 scripts/benchmark_report.py results --readme README.md --charts Docs +``` -## Conclusion +`rust/out.py` remains an entry point to the same report generator and accepts the same arguments. Output files must be named `--.txt`; a report requires both complete backends for each language and size it publishes. The C++ prototype and its dormant workflow have been removed. -As we can see in this comparison, Doublets are from 1746 to 15745 times faster than PostgreSQL in write operations, and from 100 to 9694 times faster in read operations. +| Variable | Default | Meaning | +| --- | --- | --- | +| `BENCHMARK_BACKGROUND_LINKS` | `1000` | Background point links per iteration; must be positive. | +| `BENCHMARK_LINKS` | `100` | Active links for writes; must be positive and no greater than the background. | +| `BENCHMARK_BACKEND` | `all` | `psql`, `doublets` or `all`; select one for isolated measurements. | +| `POSTGRES_CONNECTION` | `user=postgres dbname=postgres password=postgres host=localhost port=5432` | Rust connection string in postgres/libpq format, including custom hosts, ports and credentials. | +| `NPGSQL_CONNECTION` | `Host=localhost;Port=5432;Username=postgres;Password=postgres;Database=postgres` | C# Npgsql connection string. | +| `POSTGRES_VERSION` | `unknown version` | Server version recorded by the header script; CI reads `SHOW server_version`. | -To get fresh numbers, please fork the repository and rerun benchmark in GitHub Actions. +Rust PostgreSQL tests are ignored unless `--include-ignored` is supplied. C# PostgreSQL tests are explicitly skipped without `NPGSQL_CONNECTION`; CI configures both connections and runs all variants. Report tracing is off by default; set `DEBUG = True` in `scripts/benchmark_report.py` when investigating parsing. diff --git a/cpp/Benchmarks/AllBenchmarks.cpp b/cpp/Benchmarks/AllBenchmarks.cpp deleted file mode 100644 index 46e3a5c..0000000 --- a/cpp/Benchmarks/AllBenchmarks.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -const std::string options {"user=postgres dbname=postgres password=postgres host=localhost port=5432"}; -constexpr std::uint64_t BACKGROUND_LINKS {3000}; - -#include "SetupTeardown.cpp" -#include "Create.cpp" -#include "Delete.cpp" -#include "Each/Identity.cpp" -#include "Each/Concrete.cpp" -#include "Each/Outgoing.cpp" -#include "Each/Incoming.cpp" -#include "Each/All.cpp" -#include "Update.cpp" - -BENCHMARK_MAIN(); diff --git a/cpp/Benchmarks/Create.cpp b/cpp/Benchmarks/Create.cpp deleted file mode 100644 index 285bf3b..0000000 --- a/cpp/Benchmarks/Create.cpp +++ /dev/null @@ -1,158 +0,0 @@ -static void BM_PSQLCreateLinksWithoutTransaction(benchmark::State& state) { - using namespace SetupTeardown; - using namespace Platform::Data::Doublets; - using namespace PostgreSQL; - Client> table {options}; - auto background = BACKGROUND_LINKS; - Setup(table); - for (auto _: state) { - for (std::uint64_t i {}; i < state.range(0); ++i) { - CreatePoint(table); - } - state.PauseTiming(); - for (std::uint64_t i = background + state.range(0); i > background; --i) { - Delete(table, {i, i, i}); - } - background += state.range(0); - state.ResumeTiming(); - } - Teardown(table); -} - -static void BM_PSQLCreateLinksWithTransaction(benchmark::State& state) { - using namespace SetupTeardown; - using namespace Platform::Data::Doublets; - using namespace PostgreSQL; - { - Transaction> transaction {options}; - Setup(transaction); - } - auto background = BACKGROUND_LINKS; - for (auto _: state) { - { - state.PauseTiming(); - Transaction> transaction {options}; - state.ResumeTiming(); - for (std::uint64_t i {}; i < state.range(0); ++i) { - CreatePoint(transaction); - } - } - state.PauseTiming(); - { - Transaction> transaction {options}; - for (std::uint64_t i = background + state.range(0); i > background; --i) { - Delete(transaction, {i, i, i}); - } - background += state.range(0); - } - state.ResumeTiming(); - } - Transaction> transaction {options}; - Teardown(transaction); -} - -static void BM_DoubletsUnitedCreateLinksFile(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::United::Generic; - using namespace SetupTeardown; - std::filesystem::path path {"united.links"}; - UnitedMemoryLinks> storage {FileMappedResizableDirectMemory{path.string()}}; - auto handler = [&storage] (std::vector before, std::vector after) { - return storage.Constants.Continue; - }; - Setup(storage); - for (auto _: state) { - for (std::size_t i {}; i < state.range(0); ++i) { - CreatePoint(storage); - } - state.PauseTiming(); - for (std::uint64_t i = BACKGROUND_LINKS + state.range(0); i > BACKGROUND_LINKS; --i) { - storage.Delete({i, i, i}, handler); - } - state.ResumeTiming(); - } - Teardown(storage); -} - -static void BM_DoubletsUnitedCreateLinksRAM(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::United::Generic; - using namespace SetupTeardown; - HeapResizableDirectMemory memory {}; - UnitedMemoryLinks, HeapResizableDirectMemory> storage {std::move(memory)}; - auto handler = [&storage] (std::vector before, std::vector after) { - return storage.Constants.Continue; - }; - Setup(storage); - for (auto _: state) { - for (std::size_t i {}; i < state.range(0); ++i) { - CreatePoint(storage); - } - state.PauseTiming(); - for (std::uint64_t i = BACKGROUND_LINKS + state.range(0); i > BACKGROUND_LINKS; --i) { - storage.Delete({i, i, i}, handler); - } - state.ResumeTiming(); - } - Teardown(storage); -} - -static void BM_DoubletsSplitCreateLinksFile(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::Split::Generic; - using namespace SetupTeardown; - std::filesystem::path split_data {"split_data.links"}, split_index {"split_index.links"}; - SplitMemoryLinks> storage { - FileMappedResizableDirectMemory{split_data.string()}, - FileMappedResizableDirectMemory{split_index.string()} - }; - auto handler = [&storage] (std::vector before, std::vector after) { - return storage.Constants.Continue; - }; - Setup(storage); - for (auto _: state) { - for (std::size_t i {}; i < state.range(0); ++i) { - CreatePoint(storage); - } - state.PauseTiming(); - for (std::uint64_t i = BACKGROUND_LINKS + state.range(0); i > BACKGROUND_LINKS; --i) { - storage.Delete({i, i, i}, handler); - } - state.ResumeTiming(); - } - Teardown(storage); -} - -static void BM_DoubletsSplitCreateLinksRAM(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::Split::Generic; - using namespace SetupTeardown; - HeapResizableDirectMemory data {}, index {}; - SplitMemoryLinks, HeapResizableDirectMemory> storage {std::move(data), std::move(index)}; - auto handler = [&storage] (std::vector before, std::vector after) { - return storage.Constants.Continue; - }; - Setup(storage); - for (auto _: state) { - for (std::size_t i {}; i < state.range(0); ++i) { - CreatePoint(storage); - } - state.PauseTiming(); - for (std::uint64_t i = BACKGROUND_LINKS + state.range(0); i > BACKGROUND_LINKS; --i) { - storage.Delete({i, i, i}, handler); - } - state.ResumeTiming(); - } - Teardown(storage); -} - -BENCHMARK(BM_PSQLCreateLinksWithoutTransaction)->Name("BM_PSQL/Create/NonTransaction")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_PSQLCreateLinksWithTransaction)->Name("BM_PSQL/Create/Transaction")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsUnitedCreateLinksFile)->Name("BM_Doublets/United/Create/NonVolatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsUnitedCreateLinksRAM)->Name("BM_Doublets/United/Create/Volatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsSplitCreateLinksFile)->Name("BM_Doublets/Split/Create/NonVolatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsSplitCreateLinksRAM)->Name("BM_Doublets/Split/Create/Volatile")->Arg(1000)->MinWarmUpTime(20); diff --git a/cpp/Benchmarks/Delete.cpp b/cpp/Benchmarks/Delete.cpp deleted file mode 100644 index 6f0db8a..0000000 --- a/cpp/Benchmarks/Delete.cpp +++ /dev/null @@ -1,159 +0,0 @@ -static void BM_PSQLDeleteLinksWithoutTransaction(benchmark::State& state) { - using namespace SetupTeardown; - using namespace Platform::Data::Doublets; - using namespace PostgreSQL; - Client> table {options}; - Setup(table); - auto setup = [&table, &state] { - for (std::uint64_t i = BACKGROUND_LINKS + 1; i <= BACKGROUND_LINKS + state.range(0); ++i) { - CreatePoint(table); - } - }; - auto background {BACKGROUND_LINKS - state.range(0)}; - for (auto _: state) { - state.PauseTiming(); - setup(); - background += state.range(0); - state.ResumeTiming(); - for (std::uint64_t i = background + state.range(0); i > background; --i) { - Delete(table, {i, i, i}); - } - } - Teardown(table); -} - -static void BM_PSQLDeleteLinksWithTransaction(benchmark::State& state) { - using namespace SetupTeardown; - using namespace Platform::Data::Doublets; - using namespace PostgreSQL; - { - Transaction> transaction {options}; - Setup(transaction); - } - auto background {BACKGROUND_LINKS - state.range(0)}; - auto fill = [options = options, &state] { - Transaction> transaction {options}; - for (std::uint64_t i {}; i < state.range(0); ++i) { - CreatePoint(transaction); - } - }; - for (auto _: state) { - state.PauseTiming(); - fill(); - background += state.range(0); - Transaction> transaction {options}; - state.ResumeTiming(); - for (std::uint64_t i = background + state.range(0); i > background; --i) { - Delete(transaction, {i, i, i}); - } - } - Transaction> transaction {options}; - Teardown(transaction); -} - -static void BM_DoubletsUnitedDeleteLinksFile(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::United::Generic; - using namespace Platform::Collections; - using namespace SetupTeardown; - std::filesystem::path path {"united.links"}; - UnitedMemoryLinks> storage {FileMappedResizableDirectMemory{path.string()}}; - auto fill = [&storage, &state] { - for (std::size_t i {}; i < state.range(0); ++i) { - CreatePoint(storage); - } - }; - Setup(storage); - for (auto _: state) { - state.PauseTiming(); - fill(); - state.ResumeTiming(); - for (std::uint64_t i = BACKGROUND_LINKS + state.range(0); i > BACKGROUND_LINKS; --i) { - Delete(storage, {i, i, i}); - } - } - Teardown(storage); -} - -static void BM_DoubletsUnitedDeleteLinksRAM(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::United::Generic; - using namespace SetupTeardown; - HeapResizableDirectMemory memory {}; - UnitedMemoryLinks, HeapResizableDirectMemory> storage {std::move(memory)}; - auto fill = [&storage, &state] { - for (std::size_t i {}; i < state.range(0); ++i) { - CreatePoint(storage); - } - }; - Setup(storage); - for (auto _: state) { - state.PauseTiming(); - fill(); - state.ResumeTiming(); - for (std::uint64_t i = BACKGROUND_LINKS + state.range(0); i > BACKGROUND_LINKS; --i) { - Delete(storage, {i, i, i}); - } - } - Teardown(storage); -} - -static void BM_DoubletsSplitDeleteLinksFile(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::Split::Generic; - using namespace SetupTeardown; - std::filesystem::path split_index {"split_index.links"}, split_data {"split_data.links"}; - SplitMemoryLinks> storage { - FileMappedResizableDirectMemory{split_data.string()}, - FileMappedResizableDirectMemory{split_index.string()} - }; - auto fill = [&storage, &state] { - for (std::size_t i {}; i < state.range(0); ++i) { - CreatePoint(storage); - } - }; - Setup(storage); - for (auto _: state) { - state.PauseTiming(); - fill(); - state.ResumeTiming(); - for (std::uint64_t i = BACKGROUND_LINKS + state.range(0); i > BACKGROUND_LINKS; --i) { - Delete(storage, {i, i, i}); - } - } - Teardown(storage); -} - -static void BM_DoubletsSplitDeleteLinksRAM(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::Split::Generic; - using namespace SetupTeardown; - HeapResizableDirectMemory index {}, data {}; - SplitMemoryLinks, HeapResizableDirectMemory> storage {std::move(data), std::move(index)}; - auto fill = [&storage, &state] { - for (std::size_t i {}; i < state.range(0); ++i) { - CreatePoint(storage); - } - }; - Setup(storage); - for (auto _: state) { - state.PauseTiming(); - fill(); - state.ResumeTiming(); - for (std::uint64_t i = BACKGROUND_LINKS + state.range(0); i > BACKGROUND_LINKS; --i) { - Delete(storage, {i, i, i}); - } - } - Teardown(storage); -} - -BENCHMARK(BM_PSQLDeleteLinksWithoutTransaction)->Name("BM_PSQL/Delete/NonTransaction")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_PSQLDeleteLinksWithTransaction)->Name("BM_PSQL/Delete/Transaction")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsUnitedDeleteLinksFile)->Name("BM_Doublets/United/Delete/NonVolatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsUnitedDeleteLinksRAM)->Name("BM_Doublets/United/Delete/Volatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsSplitDeleteLinksFile)->Name("BM_Doublets/Split/Delete/NonVolatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsSplitDeleteLinksRAM)->Name("BM_Doublets/Split/Delete/Volatile")->Arg(1000)->MinWarmUpTime(20); diff --git a/cpp/Benchmarks/Each/All.cpp b/cpp/Benchmarks/Each/All.cpp deleted file mode 100644 index 343bfec..0000000 --- a/cpp/Benchmarks/Each/All.cpp +++ /dev/null @@ -1,121 +0,0 @@ -static void BM_PSQLEachAllWithoutTransaction(benchmark::State& state) { - using namespace SetupTeardown; - using namespace Platform::Data::Doublets; - using namespace PostgreSQL; - Client> table {options}; - auto any {table.Constants.Any}, $continue {table.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(table); - for (auto _: state) { - table.Each({any, any, any}, handler); - } - Teardown(table); -} - -static void BM_PSQLEachAllWithTransaction(benchmark::State& state) { - using namespace SetupTeardown; - using namespace Platform::Data::Doublets; - using namespace PostgreSQL; - std::uint64_t any {}, $continue {}; - { - Transaction> table {options}; - Setup(table); - any = table.Constants.Any; - $continue = table.Constants.Continue; - } - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - for (auto _: state) { - state.PauseTiming(); - Transaction> table {options}; - state.ResumeTiming(); - table.Each({any, any, any}, handler); - } - Transaction> table {options}; - Teardown(table); -} - -static void BM_DoubletsUnitedEachAllFile(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::United::Generic; - using namespace SetupTeardown; - std::filesystem::path path {"united.links"}; - UnitedMemoryLinks> storage {FileMappedResizableDirectMemory{path.string()}}; - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - storage.Each({any, any, any}, handler); - } - Teardown(storage); -} - -static void BM_DoubletsUnitedEachAllRAM(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::United::Generic; - using namespace SetupTeardown; - HeapResizableDirectMemory memory {}; - UnitedMemoryLinks, HeapResizableDirectMemory> storage {std::move(memory)}; - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - storage.Each({any, any, any}, handler); - } - Teardown(storage); -} - -static void BM_DoubletsSplitEachAllFile(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::Split::Generic; - using namespace SetupTeardown; - std::filesystem::path split_data {"split_data.links"}, split_index {"split_index.links"}; - SplitMemoryLinks> storage { - FileMappedResizableDirectMemory{split_data.string()}, - FileMappedResizableDirectMemory{split_index.string()} - }; - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - storage.Each({any, any, any}, handler); - } - Teardown(storage); -} - -static void BM_DoubletsSplitEachAllRAM(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::Split::Generic; - using namespace SetupTeardown; - HeapResizableDirectMemory data {}, index {}; - SplitMemoryLinks, HeapResizableDirectMemory> storage {std::move(data), std::move(index)}; - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - storage.Each({any, any, any}, handler); - } - Teardown(storage); -} - -BENCHMARK(BM_PSQLEachAllWithoutTransaction)->Name("BM_PSQL/Each/All/NonTransaction")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_PSQLEachAllWithTransaction)->Name("BM_PSQL/Each/All/Transaction")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsUnitedEachAllFile)->Name("BM_Doublets/United/Each/All/NonVolatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsUnitedEachAllRAM)->Name("BM_Doublets/United/Each/All/Volatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsSplitEachAllFile)->Name("BM_Doublets/Split/Each/All/NonVolatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsSplitEachAllRAM)->Name("BM_Doublets/Split/Each/All/Volatile")->Arg(1000)->MinWarmUpTime(20); diff --git a/cpp/Benchmarks/Each/Concrete.cpp b/cpp/Benchmarks/Each/Concrete.cpp deleted file mode 100644 index 076780c..0000000 --- a/cpp/Benchmarks/Each/Concrete.cpp +++ /dev/null @@ -1,169 +0,0 @@ -static void BM_PSQLEachConcreteWithoutTransaction(benchmark::State& state) { - using namespace SetupTeardown; - using namespace Platform::Data::Doublets; - using namespace PostgreSQL; - Client> table {options}; - auto any {table.Constants.Any}, $continue {table.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(table); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - table.Each({any, i, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - table.Each({any, i, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - table.Each({any, i, i}, handler); - } - } - Teardown(table); -} - -static void BM_PSQLEachConcreteWithTransaction(benchmark::State& state) { - using namespace SetupTeardown; - using namespace Platform::Data::Doublets; - using namespace PostgreSQL; - std::uint64_t any {}, $continue {}; - { - Transaction> table {options}; - Setup(table); - any = table.Constants.Any; - $continue = table.Constants.Continue; - } - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - for (auto _: state) { - state.PauseTiming(); - Transaction> table {options}; - state.ResumeTiming(); - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - table.Each({any, i, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - table.Each({any, i, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - table.Each({any, i, i}, handler); - } - } - Transaction> table {options}; - Teardown(table); -} - -static void BM_DoubletsUnitedEachConcreteFile(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::United::Generic; - using namespace SetupTeardown; - std::filesystem::path path {"united.links"}; - UnitedMemoryLinks> storage {FileMappedResizableDirectMemory{path.string()}}; - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - storage.Each({any, i, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - storage.Each({any, i, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - storage.Each({any, i, i}, handler); - } - } - Teardown(storage); -} - -static void BM_DoubletsUnitedEachConcreteRAM(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::United::Generic; - using namespace SetupTeardown; - HeapResizableDirectMemory memory {}; - UnitedMemoryLinks, HeapResizableDirectMemory> storage {std::move(memory)}; - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - storage.Each({any, i, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - storage.Each({any, i, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - storage.Each({any, i, i}, handler); - } - } - Teardown(storage); -} - -static void BM_DoubletsSplitEachConcreteFile(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::Split::Generic; - using namespace SetupTeardown; - std::filesystem::path split_data {"split_data.links"}, split_index {"split_index.links"}; - SplitMemoryLinks> storage{ - FileMappedResizableDirectMemory{split_data.string()}, - FileMappedResizableDirectMemory{split_index.string()} - }; - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - storage.Each({any, i, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - storage.Each({any, i, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - storage.Each({any, i, i}, handler); - } - } - Teardown(storage); -} - -static void BM_DoubletsSplitEachConcreteRAM(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::Split::Generic; - using namespace SetupTeardown; - HeapResizableDirectMemory data {}, index {}; - SplitMemoryLinks, HeapResizableDirectMemory> storage {std::move(data), std::move(index)}; - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - storage.Each({any, i, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - storage.Each({any, i, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - storage.Each({any, i, i}, handler); - } - } - Teardown(storage); -} - -BENCHMARK(BM_PSQLEachConcreteWithoutTransaction)->Name("BM_PSQL/Each/Concrete/NonTransaction")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_PSQLEachConcreteWithTransaction)->Name("BM_PSQL/Each/Concrete/Transaction")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsUnitedEachConcreteFile)->Name("BM_Doublets/United/Each/Concrete/NonVolatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsUnitedEachConcreteRAM)->Name("BM_Doublets/United/Each/Concrete/Volatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsSplitEachConcreteFile)->Name("BM_Doublets/Split/Each/Concrete/NonVolatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsSplitEachConcreteRAM)->Name("BM_Doublets/Split/Each/Concrete/Volatile")->Arg(1000)->MinWarmUpTime(20); diff --git a/cpp/Benchmarks/Each/Identity.cpp b/cpp/Benchmarks/Each/Identity.cpp deleted file mode 100644 index 991d088..0000000 --- a/cpp/Benchmarks/Each/Identity.cpp +++ /dev/null @@ -1,170 +0,0 @@ -static void BM_PSQLEachIdentityWithoutTransaction(benchmark::State& state) { - using namespace SetupTeardown; - using namespace Platform::Data::Doublets; - using namespace PostgreSQL; - Client> table {options}; - auto any {table.Constants.Any}; - auto $continue {table.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(table); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - table.Each({i, any, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - table.Each({i, any, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - table.Each({i, any, any}, handler); - } - } - Teardown(table); -} - -static void BM_PSQLEachIdentityWithTransaction(benchmark::State& state) { - using namespace SetupTeardown; - using namespace Platform::Data::Doublets; - using namespace PostgreSQL; - std::uint64_t any {}, $continue {}; - { - Transaction> table {options}; - Setup(table); - any = table.Constants.Any; - $continue = table.Constants.Continue; - } - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - for (auto _: state) { - state.PauseTiming(); - Transaction> table {options}; - state.ResumeTiming(); - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - table.Each({i, any, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - table.Each({i, any, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - table.Each({i, any, any}, handler); - } - } - Transaction> table {options}; - Teardown(table); -} - -static void BM_DoubletsUnitedEachIdentityFile(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::United::Generic; - using namespace SetupTeardown; - std::filesystem::path path {"united.links"}; - UnitedMemoryLinks> storage {FileMappedResizableDirectMemory{path.string()}}; - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - storage.Each({i, any, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - storage.Each({i, any, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - storage.Each({i, any, any}, handler); - } - } - Teardown(storage); -} - -static void BM_DoubletsUnitedEachIdentityRAM(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::United::Generic; - using namespace SetupTeardown; - HeapResizableDirectMemory memory {}; - UnitedMemoryLinks, HeapResizableDirectMemory> storage(std::move(memory)); - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - storage.Each({i, any, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - storage.Each({i, any, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - storage.Each({i, any, any}, handler); - } - } - Teardown(storage); -} - -static void BM_DoubletsSplitEachIdentityFile(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::Split::Generic; - using namespace SetupTeardown; - std::filesystem::path split_data {"split_data.links"}, split_index {"split_index.links"}; - SplitMemoryLinks> storage { - FileMappedResizableDirectMemory{split_data.string()}, - FileMappedResizableDirectMemory{split_index.string()} - }; - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - storage.Each({i, any, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - storage.Each({i, any, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - storage.Each({i, any, any}, handler); - } - } - Teardown(storage); -} - -static void BM_DoubletsSplitEachIdentityRAM(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::Split::Generic; - using namespace SetupTeardown; - HeapResizableDirectMemory data {}, index {}; - SplitMemoryLinks, HeapResizableDirectMemory> storage {std::move(data), std::move(index)}; - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - storage.Each({i, any, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - storage.Each({i, any, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - storage.Each({i, any, any}, handler); - } - } - Teardown(storage); -} - -BENCHMARK(BM_PSQLEachIdentityWithoutTransaction)->Name("BM_PSQL/Each/Identity/NonTransaction")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_PSQLEachIdentityWithTransaction)->Name("BM_PSQL/Each/Identity/Transaction")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsUnitedEachIdentityFile)->Name("BM_Doublets/United/Each/Identity/NonVolatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsUnitedEachIdentityRAM)->Name("BM_Doublets/United/Each/Identity/Volatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsSplitEachIdentityFile)->Name("BM_Doublets/Split/Each/Identity/NonVolatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsSplitEachIdentityRAM)->Name("BM_Doublets/Split/Each/Identity/Volatile")->Arg(1000)->MinWarmUpTime(20); \ No newline at end of file diff --git a/cpp/Benchmarks/Each/Incoming.cpp b/cpp/Benchmarks/Each/Incoming.cpp deleted file mode 100644 index 81b6b55..0000000 --- a/cpp/Benchmarks/Each/Incoming.cpp +++ /dev/null @@ -1,169 +0,0 @@ -static void BM_PSQLEachIncomingWithoutTransaction(benchmark::State& state) { - using namespace SetupTeardown; - using namespace Platform::Data::Doublets; - using namespace PostgreSQL; - Client> table {options}; - auto any {table.Constants.Any}, $continue {table.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(table); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - table.Each({any, any, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - table.Each({any, any, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - table.Each({any, any, i}, handler); - } - } - Teardown(table); -} - -static void BM_PSQLEachIncomingWithTransaction(benchmark::State& state) { - using namespace SetupTeardown; - using namespace Platform::Data::Doublets; - using namespace PostgreSQL; - std::uint64_t any {}, $continue {}; - { - Transaction> table {options}; - Setup(table); - any = table.Constants.Any; - $continue = table.Constants.Continue; - } - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - for (auto _: state) { - state.PauseTiming(); - Transaction> table {options}; - state.ResumeTiming(); - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - table.Each({any, any, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - table.Each({any, any, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - table.Each({any, any, i}, handler); - } - } - Transaction> table {options}; - Teardown(table); -} - -static void BM_DoubletsUnitedEachIncomingFile(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::United::Generic; - using namespace SetupTeardown; - std::filesystem::path path {"united.links"}; - UnitedMemoryLinks> storage {FileMappedResizableDirectMemory{path.string()}}; - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - storage.Each({any, any, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - storage.Each({any, any, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - storage.Each({any, any, i}, handler); - } - } - Teardown(storage); -} - -static void BM_DoubletsUnitedEachIncomingRAM(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::United::Generic; - using namespace SetupTeardown; - HeapResizableDirectMemory memory {}; - UnitedMemoryLinks, HeapResizableDirectMemory> storage {std::move(memory)}; - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - storage.Each({any, any, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - storage.Each({any, any, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - storage.Each({any, any, i}, handler); - } - } - Teardown(storage); -} - -static void BM_DoubletsSplitEachIncomingFile(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::Split::Generic; - using namespace SetupTeardown; - std::filesystem::path split_data {"split_data.links"}, split_index {"split_index.links"}; - SplitMemoryLinks> storage { - FileMappedResizableDirectMemory{split_data.string()}, - FileMappedResizableDirectMemory{split_index.string()} - }; - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - storage.Each({any, any, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - storage.Each({any, any, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - storage.Each({any, any, i}, handler); - } - } - Teardown(storage); -} - -static void BM_DoubletsSplitEachIncomingRAM(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::Split::Generic; - using namespace SetupTeardown; - HeapResizableDirectMemory data {}, index {}; - SplitMemoryLinks, HeapResizableDirectMemory> storage {std::move(data), std::move(index)}; - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - storage.Each({any, any, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - storage.Each({any, any, i}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - storage.Each({any, any, i}, handler); - } - } - Teardown(storage); -} - -BENCHMARK(BM_PSQLEachIncomingWithoutTransaction)->Name("BM_PSQL/Each/Incoming/NonTransaction")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_PSQLEachIncomingWithTransaction)->Name("BM_PSQL/Each/Incoming/Transaction")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsUnitedEachIncomingFile)->Name("BM_Doublets/United/Each/Incoming/NonVolatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsUnitedEachIncomingRAM)->Name("BM_Doublets/United/Each/Incoming/Volatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsSplitEachIncomingFile)->Name("BM_Doublets/Split/Each/Incoming/NonVolatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsSplitEachIncomingRAM)->Name("BM_Doublets/Split/Each/Incoming/Volatile")->Arg(1000)->MinWarmUpTime(20); diff --git a/cpp/Benchmarks/Each/Outgoing.cpp b/cpp/Benchmarks/Each/Outgoing.cpp deleted file mode 100644 index 90193a3..0000000 --- a/cpp/Benchmarks/Each/Outgoing.cpp +++ /dev/null @@ -1,169 +0,0 @@ -static void BM_PSQLEachOutgoingWithoutTransaction(benchmark::State& state) { - using namespace SetupTeardown; - using namespace Platform::Data::Doublets; - using namespace PostgreSQL; - Client> table {options}; - auto any {table.Constants.Any}, $continue {table.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(table); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - table.Each({any, i, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - table.Each({any, i, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - table.Each({any, i, any}, handler); - } - } - Teardown(table); -} - -static void BM_PSQLEachOutgoingWithTransaction(benchmark::State& state) { - using namespace SetupTeardown; - using namespace Platform::Data::Doublets; - using namespace PostgreSQL; - std::uint64_t any {}, $continue {}; - { - Transaction> table {options}; - Setup(table); - any = table.Constants.Any; - $continue = table.Constants.Continue; - } - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - for (auto _: state) { - state.PauseTiming(); - Transaction> table {options}; - state.ResumeTiming(); - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - table.Each({any, i, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - table.Each({any, i, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - table.Each({any, i, any}, handler); - } - } - Transaction> table {options}; - Teardown(table); -} - -static void BM_DoubletsUnitedEachOutgoingFile(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::United::Generic; - using namespace SetupTeardown; - std::filesystem::path path {"united.links"}; - UnitedMemoryLinks> storage {FileMappedResizableDirectMemory{path.string()}}; - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - storage.Each({any, i, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - storage.Each({any, i, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - storage.Each({any, i, any}, handler); - } - } - Teardown(storage); -} - -static void BM_DoubletsUnitedEachOutgoingRAM(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::United::Generic; - using namespace SetupTeardown; - HeapResizableDirectMemory memory {}; - UnitedMemoryLinks, HeapResizableDirectMemory> storage {std::move(memory)}; - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - storage.Each({any, i, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - storage.Each({any, i, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - storage.Each({any, i, any}, handler); - } - } - Teardown(storage); -} - -static void BM_DoubletsSplitEachOutgoingFile(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::Split::Generic; - using namespace SetupTeardown; - std::filesystem::path split_data {"split_data.links"}, split_index {"split_index.links"}; - SplitMemoryLinks> storage { - FileMappedResizableDirectMemory{split_data.string()}, - FileMappedResizableDirectMemory{split_index.string()} - }; - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - storage.Each({any, i, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - storage.Each({any, i, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - storage.Each({any, i, any}, handler); - } - } - Teardown(storage); -} - -static void BM_DoubletsSplitEachOutgoingRAM(benchmark::State& state) { - using namespace Platform::Memory; - using namespace Platform::Data::Doublets; - using namespace Memory::Split::Generic; - using namespace SetupTeardown; - HeapResizableDirectMemory data {}, index {}; - SplitMemoryLinks, HeapResizableDirectMemory> storage {std::move(data), std::move(index)}; - auto any {storage.Constants.Any}, $continue {storage.Constants.Continue}; - auto handler = [$continue] (std::vector vec) { - return $continue; - }; - Setup(storage); - for (auto _: state) { - for (std::uint64_t i = 1; i <= state.range(0); ++i) { - storage.Each({any, i, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS/2 - state.range(0)/2 + 1; i <= BACKGROUND_LINKS/2 + state.range(0)/2; ++i) { - storage.Each({any, i, any}, handler); - } - for (std::uint64_t i = BACKGROUND_LINKS - state.range(0) + 1; i <= BACKGROUND_LINKS; ++i) { - storage.Each({any, i, any}, handler); - } - } - Teardown(storage); -} - -BENCHMARK(BM_PSQLEachOutgoingWithoutTransaction)->Name("BM_PSQL/Each/Outgoing/NonTransaction")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_PSQLEachOutgoingWithTransaction)->Name("BM_PSQL/Each/Outgoing/Transaction")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsUnitedEachOutgoingFile)->Name("BM_Doublets/United/Each/Outgoing/NonVolatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsUnitedEachOutgoingRAM)->Name("BM_Doublets/United/Each/Outgoing/Volatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsSplitEachOutgoingFile)->Name("BM_Doublets/Split/Each/Outgoing/NonVolatile")->Arg(1000)->MinWarmUpTime(20); -BENCHMARK(BM_DoubletsSplitEachOutgoingRAM)->Name("BM_Doublets/Split/Each/Outgoing/Volatile")->Arg(1000)->MinWarmUpTime(20); diff --git a/cpp/Benchmarks/SetupTeardown.cpp b/cpp/Benchmarks/SetupTeardown.cpp deleted file mode 100644 index 4f0dec2..0000000 --- a/cpp/Benchmarks/SetupTeardown.cpp +++ /dev/null @@ -1,28 +0,0 @@ -namespace SetupTeardown -{ - - template - void Setup(TStorage& storage) { - using namespace Platform::Data::Doublets; - for (std::uint64_t i {}; i < BACKGROUND_LINKS; ++i) { - CreatePoint(storage); - } - } - - template