Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[extension/dbstorage] Optimize Batch performance for single-type Operations set #38026

Merged

Conversation

Fiery-Fenix
Copy link
Contributor

Description

After examine of storage.Batch() usage in Persistent Queue, I've found that in several cases when this API is used with set of operations that has same type. For example here, here, here and here
At the moment such storage.Batch() calls will generate number of SQL queries (SELECT/INSERT/DELETE), one for each Operation. But this behavior can be improved by issuing a single query with proper set of arguments taken from all provided Operations.
This PR is adding such optimization, as well as set of new Unit Tests for the new functionality and set of Benchmarks of course

Testing

Respective unit tests were added for the new functions.
Also integration tests were updated to include this optimization tests.
Result of Benchmarks for both cases - without optimization (MultiQuery) and with optimization (SingleQuery) for all currently supported SQL Drivers (sqlite3, pgx):

$ go test -bench=^BenchmarkBatch.*$ -run=^$ -benchmem .
goos: linux
goarch: amd64
pkg: github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage/dbstorage
cpu: Intel(R) Core(TM) i7-8665U CPU @ 1.90GHz
BenchmarkBatchGet/sqlite3/MultiQuery/2-8                   35890             36695 ns/op            3465 B/op         94 allocs/op
BenchmarkBatchGet/sqlite3/SingleQuery/2-8                  23973             54498 ns/op            1889 B/op         64 allocs/op
BenchmarkBatchGet/sqlite3/MultiQuery/10-8                  11325            126321 ns/op           13372 B/op        338 allocs/op
BenchmarkBatchGet/sqlite3/SingleQuery/10-8                 12354            109212 ns/op            4488 B/op        139 allocs/op
BenchmarkBatchGet/sqlite3/MultiQuery/100-8                  1380            798220 ns/op          124470 B/op       3044 allocs/op
BenchmarkBatchGet/sqlite3/SingleQuery/100-8                 2468            532443 ns/op           33335 B/op        956 allocs/op
BenchmarkBatchGet/sqlite3/MultiQuery/200-8                   758           1657263 ns/op          248036 B/op       6048 allocs/op
BenchmarkBatchGet/sqlite3/SingleQuery/200-8                 1105            988549 ns/op           64784 B/op       1957 allocs/op
BenchmarkBatchGet/sqlite3/MultiQuery/500-8                   207           6281719 ns/op          616645 B/op      15061 allocs/op
BenchmarkBatchGet/sqlite3/SingleQuery/500-8                  302           3808847 ns/op          161758 B/op       4832 allocs/op
BenchmarkBatchGet/sqlite3/MultiQuery/1000-8                   70          15244972 ns/op         1232442 B/op      30085 allocs/op
BenchmarkBatchGet/sqlite3/SingleQuery/1000-8                 219           5173644 ns/op          321643 B/op       9710 allocs/op
BenchmarkBatchGet/pgx/MultiQuery/2-8                         546           2174129 ns/op            4075 B/op         91 allocs/op
BenchmarkBatchGet/pgx/SingleQuery/2-8                        982           1160491 ns/op            1981 B/op         52 allocs/op
BenchmarkBatchGet/pgx/MultiQuery/10-8                        230           5153736 ns/op           16695 B/op        365 allocs/op
BenchmarkBatchGet/pgx/SingleQuery/10-8                       903           1333173 ns/op            4214 B/op        111 allocs/op
BenchmarkBatchGet/pgx/MultiQuery/100-8                        25          43590540 ns/op          158795 B/op       3430 allocs/op
BenchmarkBatchGet/pgx/SingleQuery/100-8                      780           1364426 ns/op           34784 B/op        841 allocs/op
BenchmarkBatchGet/pgx/MultiQuery/200-8                        20          74961744 ns/op          316640 B/op       6832 allocs/op
BenchmarkBatchGet/pgx/SingleQuery/200-8                      752           1414727 ns/op           75192 B/op       1749 allocs/op
BenchmarkBatchGet/pgx/MultiQuery/500-8                         7         173937116 ns/op          792926 B/op      17036 allocs/op
BenchmarkBatchGet/pgx/SingleQuery/500-8                      669           2099580 ns/op          199209 B/op       4460 allocs/op
BenchmarkBatchGet/pgx/MultiQuery/1000-8                        3         351418804 ns/op         1603032 B/op      34051 allocs/op
BenchmarkBatchGet/pgx/SingleQuery/1000-8                     370           3848824 ns/op          400020 B/op       8921 allocs/op
BenchmarkBatchSet/pgx/MultiQuery/2-8                         572           2602662 ns/op            1999 B/op         45 allocs/op
BenchmarkBatchSet/pgx/SingleQuery/2-8                        735           1758678 ns/op            1128 B/op         24 allocs/op
BenchmarkBatchSet/pgx/MultiQuery/10-8                        231           5143437 ns/op            6369 B/op        135 allocs/op
BenchmarkBatchSet/pgx/SingleQuery/10-8                       693           2006678 ns/op            3002 B/op         43 allocs/op
BenchmarkBatchSet/pgx/MultiQuery/100-8                        32          54685982 ns/op           55635 B/op       1130 allocs/op
BenchmarkBatchSet/pgx/SingleQuery/100-8                      253           5372262 ns/op           48075 B/op        342 allocs/op
BenchmarkBatchSet/pgx/MultiQuery/200-8                        12          93350929 ns/op          110765 B/op       2233 allocs/op
BenchmarkBatchSet/pgx/SingleQuery/200-8                      336           3661214 ns/op          102756 B/op        750 allocs/op
BenchmarkBatchSet/pgx/MultiQuery/500-8                         6         197163809 ns/op          278146 B/op       5538 allocs/op
BenchmarkBatchSet/pgx/SingleQuery/500-8                      180           7421703 ns/op          301269 B/op       1965 allocs/op
BenchmarkBatchSet/pgx/MultiQuery/1000-8                        3         432655224 ns/op          570850 B/op      11049 allocs/op
BenchmarkBatchSet/pgx/SingleQuery/1000-8                      81          13138675 ns/op          602075 B/op       3920 allocs/op
BenchmarkBatchSet/sqlite3/MultiQuery/2-8                   53840             28267 ns/op            1984 B/op         60 allocs/op
BenchmarkBatchSet/sqlite3/SingleQuery/2-8                  33325             39916 ns/op            1440 B/op         40 allocs/op
BenchmarkBatchSet/sqlite3/MultiQuery/10-8                  22402             51449 ns/op            6022 B/op        166 allocs/op
BenchmarkBatchSet/sqlite3/SingleQuery/10-8                 22303             59160 ns/op            4240 B/op         67 allocs/op
BenchmarkBatchSet/sqlite3/MultiQuery/100-8                  3145            324981 ns/op           51428 B/op       1339 allocs/op
BenchmarkBatchSet/sqlite3/SingleQuery/100-8                 4206            307055 ns/op           35144 B/op        442 allocs/op
BenchmarkBatchSet/sqlite3/MultiQuery/200-8                  1855            622018 ns/op          101979 B/op       2641 allocs/op
BenchmarkBatchSet/sqlite3/SingleQuery/200-8                 1612            752589 ns/op           71433 B/op        944 allocs/op
BenchmarkBatchSet/sqlite3/MultiQuery/500-8                   778           1502507 ns/op          250439 B/op       6541 allocs/op
BenchmarkBatchSet/sqlite3/SingleQuery/500-8                  669           1722224 ns/op          176874 B/op       2292 allocs/op
BenchmarkBatchSet/sqlite3/MultiQuery/1000-8                  391           3379177 ns/op          498817 B/op      13042 allocs/op
BenchmarkBatchSet/sqlite3/SingleQuery/1000-8                 290           3775039 ns/op          354891 B/op       4644 allocs/op
BenchmarkBatchDelete/sqlite3/MultiQuery/2-8                50040             22934 ns/op            2531 B/op         69 allocs/op
BenchmarkBatchDelete/sqlite3/SingleQuery/2-8               42121             29979 ns/op            1072 B/op         37 allocs/op
BenchmarkBatchDelete/sqlite3/MultiQuery/10-8               27229             39651 ns/op            5930 B/op        167 allocs/op
BenchmarkBatchDelete/sqlite3/SingleQuery/10-8              33789             40071 ns/op            2336 B/op         55 allocs/op
BenchmarkBatchDelete/sqlite3/MultiQuery/100-8               3441            307201 ns/op           44147 B/op       1251 allocs/op
BenchmarkBatchDelete/sqlite3/SingleQuery/100-8              6615            189322 ns/op           17256 B/op        240 allocs/op
BenchmarkBatchDelete/sqlite3/MultiQuery/200-8               2604            453754 ns/op           86620 B/op       2452 allocs/op
BenchmarkBatchDelete/sqlite3/SingleQuery/200-8              3252            404133 ns/op           33480 B/op        541 allocs/op
BenchmarkBatchDelete/sqlite3/MultiQuery/500-8               1090           1000761 ns/op          211096 B/op       6052 allocs/op
BenchmarkBatchDelete/sqlite3/SingleQuery/500-8              1369            786293 ns/op           83082 B/op       1284 allocs/op
BenchmarkBatchDelete/sqlite3/MultiQuery/1000-8               661           2085153 ns/op          419392 B/op      12053 allocs/op
BenchmarkBatchDelete/sqlite3/SingleQuery/1000-8              631           1683227 ns/op          165130 B/op       2629 allocs/op
BenchmarkBatchDelete/pgx/MultiQuery/2-8                      693           1629475 ns/op            2873 B/op         63 allocs/op
BenchmarkBatchDelete/pgx/SingleQuery/2-8                    1302            859318 ns/op             849 B/op         21 allocs/op
BenchmarkBatchDelete/pgx/MultiQuery/10-8                     270           4547262 ns/op            6597 B/op        145 allocs/op
BenchmarkBatchDelete/pgx/SingleQuery/10-8                    972           1078239 ns/op            1649 B/op         31 allocs/op
BenchmarkBatchDelete/pgx/MultiQuery/100-8                     33          37797248 ns/op           48675 B/op       1050 allocs/op
BenchmarkBatchDelete/pgx/SingleQuery/100-8                   992           1332331 ns/op           16730 B/op        130 allocs/op
BenchmarkBatchDelete/pgx/MultiQuery/200-8                     16          70891371 ns/op           95467 B/op       2052 allocs/op
BenchmarkBatchDelete/pgx/SingleQuery/200-8                   981           1251028 ns/op           40217 B/op        338 allocs/op
BenchmarkBatchDelete/pgx/MultiQuery/500-8                      6         276334286 ns/op          239109 B/op       5057 allocs/op
BenchmarkBatchDelete/pgx/SingleQuery/500-8                   511           2928010 ns/op          105371 B/op        948 allocs/op
BenchmarkBatchDelete/pgx/MultiQuery/1000-8                     3         443579390 ns/op          492162 B/op      10070 allocs/op
BenchmarkBatchDelete/pgx/SingleQuery/1000-8                  459           2447974 ns/op          212328 B/op       1887 allocs/op
PASS
ok      github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage/dbstorage   160.034s

@Fiery-Fenix Fiery-Fenix requested review from dmitryax, atoulme and a team as code owners February 18, 2025 15:36
@Fiery-Fenix Fiery-Fenix force-pushed the feat/dbstorage-batch-optimization branch from 95f6d80 to 5b4fd9a Compare February 18, 2025 15:38
@Fiery-Fenix
Copy link
Contributor Author

Also, in context of future batchprocessor deprecation in favor of inside exporter helper batch implementation - performance for such Batch() calls might become very critical. Because Persistent Queue instead of few already aggregated records (aggregated by batchprocessor) will start receiving bunch of not aggregated data which will generate big load on DB, if it's used as Persistent Queue Storage

@atoulme
Copy link
Contributor

atoulme commented Feb 20, 2025

Is the benchmark test in main? Can you run before/after and compare with benchstat?

@Fiery-Fenix
Copy link
Contributor Author

Is the benchmark test in main? Can you run before/after and compare with benchstat?

That's a new benchmarks, not currently present in main
But it's quite easy to compare this changes with previous behavior
Here is benchstat results:

benchstat -row .name,/backend,/rows -col /op results.txt
goos: linux
goarch: amd64
pkg: github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage/dbstorage
cpu: Intel(R) Core(TM) i7-8665U CPU @ 1.90GHz
                         │   MultiQuery   │             SingleQuery              │
                         │     sec/op     │    sec/op     vs base                │
BatchGet sqlite3 2           26.02µ ± 23%   39.44µ ± 17%  +51.55% (p=0.000 n=10)
BatchGet sqlite3 10          62.73µ ±  9%   42.29µ ± 12%  -32.58% (p=0.000 n=10)
BatchGet sqlite3 100         586.0µ ± 12%   207.1µ ±  8%  -64.66% (p=0.000 n=10)
BatchGet sqlite3 200        1059.3µ ± 20%   423.2µ ±  9%  -60.04% (p=0.000 n=10)
BatchGet sqlite3 500        2809.3µ ± 30%   974.3µ ±  7%  -65.32% (p=0.000 n=10)
BatchGet sqlite3 1000        5.833m ± 16%   1.840m ±  8%  -68.45% (p=0.000 n=10)
BatchGet pgx 2               1.489m ± 14%   1.013m ± 14%  -31.96% (p=0.000 n=10)
BatchGet pgx 10             4063.1µ ± 10%   996.3µ ± 15%  -75.48% (p=0.000 n=10)
BatchGet pgx 100            34.946m ± 29%   1.070m ±  8%  -96.94% (p=0.000 n=10)
BatchGet pgx 200            69.846m ± 13%   1.238m ±  7%  -98.23% (p=0.000 n=10)
BatchGet pgx 500           177.472m ±  7%   1.519m ± 13%  -99.14% (p=0.000 n=10)
BatchGet pgx 1000          324.701m ± 10%   2.362m ±  8%  -99.27% (p=0.000 n=10)
BatchSet sqlite3 2           26.92µ ± 19%   41.83µ ± 17%  +55.39% (p=0.000 n=10)
BatchSet sqlite3 10          88.50µ ± 31%   53.73µ ± 22%  -39.29% (p=0.000 n=10)
BatchSet sqlite3 100         586.5µ ± 28%   209.7µ ±  9%  -64.25% (p=0.000 n=10)
BatchSet sqlite3 200        1175.9µ ± 21%   481.3µ ± 24%  -59.07% (p=0.000 n=10)
BatchSet sqlite3 500         3.325m ± 19%   1.012m ± 35%  -69.58% (p=0.000 n=10)
BatchSet sqlite3 1000        6.243m ± 20%   2.051m ± 11%  -67.14% (p=0.000 n=10)
BatchSet pgx 2               2.385m ± 10%   1.440m ± 25%  -39.61% (p=0.000 n=10)
BatchSet pgx 10             5194.4µ ± 14%   936.0µ ± 19%  -81.98% (p=0.000 n=10)
BatchSet pgx 100            33.238m ± 18%   1.021m ± 11%  -96.93% (p=0.000 n=10)
BatchSet pgx 200            66.221m ± 13%   1.130m ± 10%  -98.29% (p=0.000 n=10)
BatchSet pgx 500           154.477m ± 12%   1.592m ±  8%  -98.97% (p=0.000 n=10)
BatchSet pgx 1000          351.467m ± 17%   2.306m ± 14%  -99.34% (p=0.000 n=10)
BatchDelete sqlite3 2        31.77µ ± 26%   38.04µ ± 24%  +19.72% (p=0.029 n=10)
BatchDelete sqlite3 10       71.69µ ± 53%   49.30µ ± 36%  -31.23% (p=0.007 n=10)
BatchDelete sqlite3 100      638.6µ ± 19%   220.0µ ± 22%  -65.56% (p=0.000 n=10)
BatchDelete sqlite3 200     1141.4µ ± 14%   667.0µ ± 79%  -41.56% (p=0.019 n=10)
BatchDelete sqlite3 500      4.095m ± 37%   1.800m ± 32%  -56.04% (p=0.000 n=10)
BatchDelete sqlite3 1000     7.040m ± 37%   3.232m ± 16%  -54.10% (p=0.000 n=10)
BatchDelete pgx 2           1646.4µ ± 14%   975.9µ ± 11%  -40.73% (p=0.000 n=10)
BatchDelete pgx 10          3958.5µ ± 14%   963.1µ ±  5%  -75.67% (p=0.000 n=10)
BatchDelete pgx 100         30.822m ± 19%   1.030m ± 23%  -96.66% (p=0.000 n=10)
BatchDelete pgx 200         59.838m ± 14%   1.083m ± 12%  -98.19% (p=0.000 n=10)
BatchDelete pgx 500        151.759m ± 12%   1.457m ± 11%  -99.04% (p=0.000 n=10)
BatchDelete pgx 1000       345.208m ±  9%   2.547m ± 18%  -99.26% (p=0.000 n=10)
geomean                      4.172m         612.0µ        -85.33%

                         │  MultiQuery   │             SingleQuery              │
                         │     B/op      │     B/op      vs base                │
BatchGet sqlite3 2          3.156Ki ± 0%   1.547Ki ± 0%  -50.97% (p=0.000 n=10)
BatchGet sqlite3 10        11.955Ki ± 0%   3.177Ki ± 0%  -73.43% (p=0.000 n=10)
BatchGet sqlite3 100       110.48Ki ± 0%   21.52Ki ± 0%  -80.52% (p=0.000 n=10)
BatchGet sqlite3 200       219.97Ki ± 0%   41.33Ki ± 0%  -81.21% (p=0.000 n=10)
BatchGet sqlite3 500        545.6Ki ± 0%   103.0Ki ± 0%  -81.13% (p=0.000 n=10)
BatchGet sqlite3 1000      1089.5Ki ± 0%   204.1Ki ± 0%  -81.26% (p=0.000 n=10)
BatchGet pgx 2              3.824Ki ± 0%   1.719Ki ± 0%  -55.06% (p=0.000 n=10)
BatchGet pgx 10            15.521Ki ± 0%   3.021Ki ± 0%  -80.54% (p=0.000 n=10)
BatchGet pgx 100           147.21Ki ± 0%   23.02Ki ± 0%  -84.36% (p=0.000 n=10)
BatchGet pgx 200           293.87Ki ± 0%   51.53Ki ± 0%  -82.47% (p=0.000 n=10)
BatchGet pgx 500            736.3Ki ± 0%   139.7Ki ± 0%  -81.02% (p=0.000 n=10)
BatchGet pgx 1000          1479.5Ki ± 1%   281.0Ki ± 0%  -81.01% (p=0.000 n=10)
BatchSet sqlite3 2          3.156Ki ± 0%   1.549Ki ± 0%  -50.93% (p=0.000 n=10)
BatchSet sqlite3 10        11.953Ki ± 0%   3.178Ki ± 0%  -73.41% (p=0.000 n=10)
BatchSet sqlite3 100       110.49Ki ± 0%   21.51Ki ± 0%  -80.53% (p=0.000 n=10)
BatchSet sqlite3 200       219.98Ki ± 0%   41.33Ki ± 0%  -81.21% (p=0.000 n=10)
BatchSet sqlite3 500        545.8Ki ± 0%   103.0Ki ± 0%  -81.13% (p=0.000 n=10)
BatchSet sqlite3 1000      1089.6Ki ± 0%   204.2Ki ± 0%  -81.26% (p=0.000 n=10)
BatchSet pgx 2              3.824Ki ± 0%   1.720Ki ± 0%  -55.03% (p=0.000 n=10)
BatchSet pgx 10            15.529Ki ± 0%   3.021Ki ± 0%  -80.55% (p=0.000 n=10)
BatchSet pgx 100           147.23Ki ± 0%   23.02Ki ± 0%  -84.36% (p=0.000 n=10)
BatchSet pgx 200           293.70Ki ± 0%   51.52Ki ± 0%  -82.46% (p=0.000 n=10)
BatchSet pgx 500            735.2Ki ± 0%   139.7Ki ± 0%  -80.99% (p=0.000 n=10)
BatchSet pgx 1000          1487.1Ki ± 1%   281.0Ki ± 0%  -81.10% (p=0.000 n=10)
BatchDelete sqlite3 2       3.157Ki ± 0%   1.547Ki ± 0%  -51.00% (p=0.000 n=10)
BatchDelete sqlite3 10     11.956Ki ± 0%   3.177Ki ± 0%  -73.43% (p=0.000 n=10)
BatchDelete sqlite3 100    110.50Ki ± 0%   21.52Ki ± 0%  -80.53% (p=0.000 n=10)
BatchDelete sqlite3 200    219.99Ki ± 0%   41.32Ki ± 0%  -81.22% (p=0.000 n=10)
BatchDelete sqlite3 500     545.9Ki ± 0%   103.1Ki ± 0%  -81.12% (p=0.000 n=10)
BatchDelete sqlite3 1000   1089.8Ki ± 0%   204.4Ki ± 0%  -81.25% (p=0.000 n=10)
BatchDelete pgx 2           3.826Ki ± 0%   1.719Ki ± 0%  -55.06% (p=0.000 n=10)
BatchDelete pgx 10         15.526Ki ± 0%   3.019Ki ± 0%  -80.56% (p=0.000 n=10)
BatchDelete pgx 100        147.25Ki ± 0%   23.02Ki ± 0%  -84.36% (p=0.000 n=10)
BatchDelete pgx 200        293.60Ki ± 0%   51.52Ki ± 0%  -82.45% (p=0.000 n=10)
BatchDelete pgx 500         735.3Ki ± 0%   139.7Ki ± 0%  -80.99% (p=0.000 n=10)
BatchDelete pgx 1000       1487.0Ki ± 1%   281.0Ki ± 0%  -81.10% (p=0.000 n=10)
geomean                     103.6Ki        23.03Ki       -77.77%

                         │  MultiQuery  │             SingleQuery             │
                         │  allocs/op   │  allocs/op   vs base                │
BatchGet sqlite3 2           80.00 ± 0%    45.00 ± 0%  -43.75% (p=0.000 n=10)
BatchGet sqlite3 10         269.00 ± 0%    64.00 ± 0%  -76.21% (p=0.000 n=10)
BatchGet sqlite3 100        2344.0 ± 0%    251.0 ± 0%  -89.29% (p=0.000 n=10)
BatchGet sqlite3 200        4646.0 ± 0%    552.0 ± 0%  -88.12% (p=0.000 n=10)
BatchGet sqlite3 500       11.547k ± 0%   1.316k ± 0%  -88.60% (p=0.000 n=10)
BatchGet sqlite3 1000      23.050k ± 0%   2.683k ± 0%  -88.36% (p=0.000 n=10)
BatchGet pgx 2               83.00 ± 0%    40.00 ± 0%  -51.81% (p=0.000 n=10)
BatchGet pgx 10             325.00 ± 0%    51.00 ± 0%  -84.31% (p=0.000 n=10)
BatchGet pgx 100            3030.0 ± 0%    151.0 ± 0%  -95.02% (p=0.000 n=10)
BatchGet pgx 200            6033.0 ± 0%    359.0 ± 0%  -94.05% (p=0.000 n=10)
BatchGet pgx 500           15037.0 ± 0%    969.0 ± 0%  -93.56% (p=0.000 n=10)
BatchGet pgx 1000          30.046k ± 0%   1.929k ± 0%  -93.58% (p=0.000 n=10)
BatchSet sqlite3 2           80.00 ± 0%    45.00 ± 0%  -43.75% (p=0.000 n=10)
BatchSet sqlite3 10         269.00 ± 0%    64.00 ± 0%  -76.21% (p=0.000 n=10)
BatchSet sqlite3 100        2344.0 ± 0%    251.0 ± 0%  -89.29% (p=0.000 n=10)
BatchSet sqlite3 200        4646.0 ± 0%    552.0 ± 0%  -88.12% (p=0.000 n=10)
BatchSet sqlite3 500       11.547k ± 0%   1.317k ± 0%  -88.60% (p=0.000 n=10)
BatchSet sqlite3 1000      23.052k ± 0%   2.683k ± 0%  -88.36% (p=0.000 n=10)
BatchSet pgx 2               83.00 ± 0%    40.00 ± 0%  -51.81% (p=0.000 n=10)
BatchSet pgx 10             325.00 ± 0%    51.00 ± 0%  -84.31% (p=0.000 n=10)
BatchSet pgx 100            3030.0 ± 0%    151.0 ± 0%  -95.02% (p=0.000 n=10)
BatchSet pgx 200            6032.5 ± 0%    359.0 ± 0%  -94.05% (p=0.000 n=10)
BatchSet pgx 500           15036.0 ± 0%    969.0 ± 0%  -93.56% (p=0.000 n=10)
BatchSet pgx 1000          30.048k ± 0%   1.929k ± 0%  -93.58% (p=0.000 n=10)
BatchDelete sqlite3 2        80.00 ± 0%    45.00 ± 0%  -43.75% (p=0.000 n=10)
BatchDelete sqlite3 10      269.00 ± 0%    64.00 ± 0%  -76.21% (p=0.000 n=10)
BatchDelete sqlite3 100     2344.0 ± 0%    251.0 ± 0%  -89.29% (p=0.000 n=10)
BatchDelete sqlite3 200     4646.0 ± 0%    552.0 ± 0%  -88.12% (p=0.000 n=10)
BatchDelete sqlite3 500    11.548k ± 0%   1.317k ± 0%  -88.60% (p=0.000 n=10)
BatchDelete sqlite3 1000   23.052k ± 0%   2.685k ± 0%  -88.35% (p=0.000 n=10)
BatchDelete pgx 2            83.00 ± 0%    40.00 ± 0%  -51.81% (p=0.000 n=10)
BatchDelete pgx 10          325.00 ± 0%    51.00 ± 0%  -84.31% (p=0.000 n=10)
BatchDelete pgx 100         3030.0 ± 0%    151.0 ± 0%  -95.02% (p=0.000 n=10)
BatchDelete pgx 200         6032.0 ± 0%    359.0 ± 0%  -94.05% (p=0.000 n=10)
BatchDelete pgx 500        15036.5 ± 0%    969.0 ± 0%  -93.56% (p=0.000 n=10)
BatchDelete pgx 1000       30.047k ± 0%   1.929k ± 0%  -93.58% (p=0.000 n=10)
geomean                     2.214k         285.3       -87.11%

As you can see there are only few cases with performance degradation, but all other case has impressive performance improvements alongside with much lower resource utilization

@atoulme
Copy link
Contributor

atoulme commented Feb 21, 2025

alright, that's impressive.

@swiatekm
Copy link
Contributor

Something I'm a bit concerned about is that, while the benchmark results are very impressive, they show a performance regression in what I believe to be the most common case for this extension: a single GET operation.

BatchGet sqlite3 2           26.02µ ± 23%   39.44µ ± 17%  +51.55% (p=0.000 n=10)

Why does this regression happen? Intuitively, I'd expect no change.

@Fiery-Fenix
Copy link
Contributor Author

Something I'm a bit concerned about is that, while the benchmark results are very impressive, they show a performance regression in what I believe to be the most common case for this extension: a single GET operation.

BatchGet sqlite3 2           26.02µ ± 23%   39.44µ ± 17%  +51.55% (p=0.000 n=10)

Why does this regression happen? Intuitively, I'd expect no change.

Actually, this regression has quite simple explanation:
Because aggregated/non-aggregate Batch decision is made deeply inside client - I have to invent some way how to switch Batch() between those modes for testing and benchmarking purposes
So, for MultiQuery (when all Operations are executed as a separate queries) I have added 1 extra query with different Operation type
That's means that BatchGet with type MultiQuery and 2 Operations are actually executing 3 Operations (1 Delete and 2 Get) while SingleQuery executes exactly 2 Operation (2 Get)
Logically, it should bring at least 33% "performance degradation" in such benchmarks
Yes, that's made such benchmarks a little bit incorrect, but even in such approach it demonstrates very huge performance improvement
I believe that real world performance of aggregated Batch will be at least comparable with non-aggregated Batch, not lower

@atoulme atoulme merged commit 737fa7f into open-telemetry:main Mar 6, 2025
160 checks passed
@github-actions github-actions bot added this to the next release milestone Mar 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants