Перейти к основному содержимому
Нормативная версия документации - английская

Эта страница переведена с английского языковой моделью. При любом расхождении верен английский оригинал.

Бенчмарки

Во что ruststream-sqlx обходится на каждом сообщении: пропускная способность против сырого цикла sqlx, outbox как плагин, инструкции и выделения памяти его кода.

Против сырого цикла sqlx​

Первый график прогоняет каждый сценарий тремя способами на PostgreSQL из стенда. «Сырой цикл sqlx» - написанный вручную цикл, который выполняет те же операторы, что брокер выполняет для той же таблицы, в том же порядке, на пуле, построенном так же; он берёт их у диалекта, поэтому два цикла не могут разойтись. «Крейт вручную» работает с подпиской или издателем этого крейта собственным циклом, без рантайма. «Сервис RustStream» - сервис, который пишет пользователь: таблица с #[derive(Inbox)], обработчик #[subscriber] и приложение. Первая разность показывает, во что этот крейт обходится поверх операторов, которые он выполняет, а вторая - что сверху добавляет рантайм.

Каждый цикл изображён полосой от лучшего круга до самого медленного: точка отмечает лучший круг, засечка - медиану. Ноль оси - лучший круг сырого цикла, и точка правее нуля значит, что цикл медленнее. Пустая точка отмечает цикл, у которого разница с сырым циклом меньше разброса кругов. Таблица под графиком печатает лучший круг, а в скобках медиану.

Каждое сообщение стоит как минимум захвата, завершения и фиксации, и каждое из них - обмен с базой данных. Строка с отметкой «упирается в базу данных» - та, где сырой цикл хотя бы половину времени каждого сообщения ждал этих обменов. Крейт и рантайм тогда выполняют свою работу внутри ожидания, которое оплачивает и сырой цикл, и строка даёт нижнюю границу их стоимости, а не её измерение.

Outbox как плагин​

Outbox работает поверх любого брокера, поэтому измеряется как стоимость для обычного приложения: одно приложение в трёх вариантах, поверх Redis Pub/Sub из стенда через ruststream-fred и PostgreSQL из стенда. «Без outbox» - приложение, которое пользователь пишет без него. «Outbox, написанный вручную» - то же приложение, где запись вставляется перед каждой публикацией, а в обработчике получается и отмечается, на голом sqlx. «Outbox крейта» - то же приложение с реестром этого крейта, двумя его слоями и повторной публикацией. Относительно варианта без outbox график показывает, во что вообще обходится отслеживание сообщения, а относительно ручного outbox - что механизм крейта добавляет к операторам, которые пользователь выполнял бы в любом случае.

Стоимость кода​

График стоимости считает, во что одно сообщение обходится на потоке сервиса: инструкции под callgrind и выделения памяти под DHAT, в установившемся режиме, против PostgreSQL из стенда. В счёт входят рантайм, этот крейт и кодирование и декодирование в драйвере sqlx на этом потоке; сервер базы данных - другой процесс, и в счёт он не входит. «Холодный старт» - разовая стоимость запуска сервиса: открытие соединений пула, проверки брокера при старте и первая доставка. Счёт outbox запускает те же приложения поверх MemoryBroker, поэтому транспорта в его числе нет.

Результаты​

InboxНасколько каждый цикл отстаёт от лучшего круга сырого цикла
  • Сырой цикл sqlx
  • Крейт вручную
  • Сервис RustStream
  • круги, от лучшего до самого медленного
  • лучший круг
  • медианный круг
  • разброс кругов
  • неразличимо

ruststream-sqlx 0.7.0 on ruststream 0.7.1, AMD Ryzen 9 7900X 12-Core Processor, Linux 7.2.11-x64v3-xanmod1-1, postgres:17-alpine, mysql:8.0, redis:7-alpine in Docker on the host network, without durability; SQLite bundled with sqlx, on a local file in WAL mode; the outbox over MemoryBroker in the code table and over Redis Pub/Sub in the wall clock, измерено 2026-10-18. Как сняты числа

row lock claim, JSON decode into a small struct, delete each
  • неразличимо
  • +2.1% (упирается в базу данных)
row lock claim, reply inserted through this crate's default publisher, delete each
  • неразличимо
  • неразличимо (упирается в базу данных)
row lock claim in batches of 64, delete each
  • неразличимо
  • неразличимо (упирается в базу данных)
lease claim, JSON decode into a small struct, delete each
  • -3%
  • -2.5%
advisory lock claim, JSON decode into a small struct, delete each
  • неразличимо
  • неразличимо
by-name subscription, row lock claim, delete each
  • неразличимо
  • неразличимо (упирается в базу данных)
row mode, the row decoded by the driver, delete each
  • неразличимо
  • неразличимо (упирается в базу данных)
repository publish, one insert each
  • неразличимо
  • неразличимо (упирается в базу данных)
routed publish, one insert each
  • неразличимо
  • неразличимо (упирается в базу данных)
Показать числа таблицей
СценарийСырой цикл sqlxКрейт вручнуюСервис RustStreamОверхед
row lock claim, JSON decode into a small struct, delete each6 149 msg/s (6 103)6 136 msg/s (5 986) (неразличимо к сырому циклу)6 018 msg/s (5 996)+2.1% (упирается в базу данных)
row lock claim, reply inserted through this crate's default publisher, delete each5 150 msg/s (4 984)5 103 msg/s (5 092) (неразличимо к сырому циклу)5 007 msg/s (4 937)неразличимо (упирается в базу данных)
row lock claim in batches of 64, delete each29 198 msg/s (29 006)29 043 msg/s (28 629) (неразличимо к сырому циклу)28 724 msg/s (28 676)неразличимо (упирается в базу данных)
lease claim, JSON decode into a small struct, delete each3 125 msg/s (3 098)3 219 msg/s (3 193) (-3% к сырому циклу)3 202 msg/s (3 177)-2.5%
advisory lock claim, JSON decode into a small struct, delete each4 611 msg/s (4 572)4 558 msg/s (4 462) (неразличимо к сырому циклу)4 565 msg/s (4 295)неразличимо
by-name subscription, row lock claim, delete each6 089 msg/s (5 910)6 025 msg/s (5 773) (неразличимо к сырому циклу)5 980 msg/s (5 784)неразличимо (упирается в базу данных)
row mode, the row decoded by the driver, delete each5 805 msg/s (5 771)5 769 msg/s (5 662) (неразличимо к сырому циклу)5 759 msg/s (5 742)неразличимо (упирается в базу данных)
repository publish, one insert each26 723 msg/s (26 721)27 814 msg/s (27 485) (неразличимо к сырому циклу)27 640 msg/s (26 771)неразличимо (упирается в базу данных)
routed publish, one insert each29 182 msg/s (27 701)27 947 msg/s (26 567) (неразличимо к сырому циклу)27 295 msg/s (26 896)неразличимо (упирается в базу данных)
Плагин outboxНасколько каждый цикл отстаёт от лучшего круга приложения без outbox
  • Без outbox
  • Outbox, написанный вручную
  • Outbox крейта
  • круги, от лучшего до самого медленного
  • лучший круг
  • медианный круг
  • разброс кругов
  • неразличимо
outbox plugin, an untracked message through both layers
  • неразличимо
outbox plugin, a tracked publish from outside a handler
  • +76.2%
  • +75.9% (неразличимо к ручному)
outbox plugin, a tracked delivery fetched and marked
  • +86.3%
  • +86.5% (неразличимо к ручному)
outbox plugin, a tracked round trip: recorded, delivered, fetched and marked
  • +84.9%
  • +85.2% (неразличимо к ручному)
Показать числа таблицей
СценарийБез outboxOutbox, написанный вручнуюOutbox крейтаОверхедК outbox, написанному вручную
outbox plugin, an untracked message through both layers53 058 msg/s (52 720)-53 160 msg/s (52 178)неразличимо-
outbox plugin, a tracked publish from outside a handler66 275 msg/s (66 203)15 761 msg/s (15 425) (+76.2% к варианту без outbox)15 961 msg/s (15 395)+75.9%неразличимо
outbox plugin, a tracked delivery fetched and marked64 200 msg/s (61 442)8 821 msg/s (8 600) (+86.3% к варианту без outbox)8 682 msg/s (8 635)+86.5%неразличимо
outbox plugin, a tracked round trip: recorded, delivered, fetched and marked54 357 msg/s (53 776)8 191 msg/s (8 143) (+84.9% к варианту без outbox)8 044 msg/s (8 025)+85.2%неразличимо
Стоимость кода

AMD Ryzen 9 7900X 12-Core Processor, x86_64, 427-5912 MHz, 12 physical, 24 logical, 62.4 GiB, unknown, Linux 7.2.11-x64v3-xanmod1-1, 1.99.0, 3.25.1, bench, inheriting release (opt-level = 3, lto = fat, codegen-units = 16, debug = line-tables-only), ruststream-sqlx inbox,outbox,postgres,mysql,sqlite,chrono; ruststream macros,json,memory; ruststream-fred default. ruststream-sqlx 0.7.0, ruststream 0.7.1, измерено 2026-10-18.

Инструкции
Выделения
row lock claim, JSON decode into a small struct, delete each
44 796,1
32
row lock claim, reply inserted through this crate's default publisher, delete each
66 613,4
44
row lock claim in batches of 64, delete each
14 281,5
12,6
lease claim, JSON decode into a small struct, delete each
51 541,4
28
advisory lock claim, JSON decode into a small struct, delete each
66 800,8
47,1
by-name subscription, row lock claim, delete each
47 474,3
32
row mode, the row decoded by the driver, delete each
43 674,9
32
repository publish, one insert each
23 890,9
15
routed publish, one insert each
23 429
15
outbox plugin, an untracked message through both layers
7 238,2
6
outbox plugin, a tracked publish from outside a handler
23 232,9
15
outbox plugin, a tracked delivery fetched and marked
51 016,7
30
outbox plugin, a tracked round trip: recorded, delivered, fetched and marked
75 639,3
42,1
Показать числа таблицей
СценарийИнструкцииВыделенияХолодный старт
row lock claim, JSON decode into a small struct, delete each44 796,132334 632 / 355
row lock claim, reply inserted through this crate's default publisher, delete each66 613,444337 677 / 353
row lock claim in batches of 64, delete each14 281,512,6334 178 / 358
lease claim, JSON decode into a small struct, delete each51 541,428397 875 / 393
advisory lock claim, JSON decode into a small struct, delete each66 800,847,1421 572 / 494
by-name subscription, row lock claim, delete each47 474,332356 127 / 359
row mode, the row decoded by the driver, delete each43 674,932338 529 / 364
repository publish, one insert each23 890,915144 459 / 128
routed publish, one insert each23 42915145 266 / 129
outbox plugin, an untracked message through both layers7 238,26251 239 / 250
outbox plugin, a tracked publish from outside a handler23 232,915183 040 / 161
outbox plugin, a tracked delivery fetched and marked51 016,730280 164 / 271
outbox plugin, a tracked round trip: recorded, delivered, fetched and marked75 639,342,1328 380 / 311

Счёт стоит рядом с циклами, против которых он измерен: для inbox это сырой цикл sqlx, а для outbox - приложение без outbox и приложение с outbox, написанным вручную.

СценарийСервис, инструкцииСырой цикл, инструкцииСервис, выделенияСырой цикл, выделения
row lock claim, JSON decode into a small struct, delete each44 796,140 310,63233
row lock claim, reply inserted through this crate's default publisher, delete each66 613,460 551,54445
row lock claim in batches of 64, delete each14 281,512 300,712,612,4
lease claim, JSON decode into a small struct, delete each51 541,447 1332828
advisory lock claim, JSON decode into a small struct, delete each66 800,858 844,847,147,1
by-name subscription, row lock claim, delete each47 474,340 384,53233
row mode, the row decoded by the driver, delete each43 674,939 836,33233
repository publish, one insert each23 890,920 830,81512
routed publish, one insert each23 42920 830,81512
СценарийИнструкции (без outbox / вручную / outbox)Выделения (без outbox / вручную / outbox)
outbox plugin, an untracked message through both layers6 788,2 / - / 7 238,26 / - / 6
outbox plugin, a tracked publish from outside a handler742,2 / 22 349,9 / 23 232,92 / 16 / 15
outbox plugin, a tracked delivery fetched and marked4 877,7 / 47 021,6 / 51 016,77 / 30 / 30
outbox plugin, a tracked round trip: recorded, delivered, fetched and marked6 821,3 / 68 347,8 / 75 639,36 / 39 / 42,1

Пропускная способность​

Заполненную таблицу на каждой базе данных разбирает одна подписка, смонтированная с workers(n), на пуле из 16 соединений, по одной доставке или пакетами по 64. PostgreSQL и MySQL используют форму блокировки строк. SQLite использует форму аренды, потому что у неё нет блокировок строк. Сырой цикл запускает n задач на одном пуле, и каждая захватывает, читает и удаляет, пока её захват не вернётся пустым. Цикл крейта запускает n подписок на том же пуле, каждую на собственном брокере. Сервис запускает одну подписку, которая захватывает для всех своих воркеров. Ячейки outbox монтируют ретранслятор и приёмник с workers(n) в каждом из трёх вариантов outbox.

Postgres, форма блокировки строкНасколько каждый цикл отстаёт от лучшего круга сырого цикла
  • Сырой цикл sqlx
  • Крейт вручную
  • Сервис RustStream
  • круги, от лучшего до самого медленного
  • лучший круг
  • медианный круг
  • разброс кругов
  • неразличимо

ruststream-sqlx 0.7.0 on ruststream 0.7.1, измерено 2026-10-18. Как сняты числа

по одной, workers(1)
  • неразличимо
  • неразличимо
по одной, workers(4)
  • неразличимо
  • +18.5%
по одной, workers(8)
  • неразличимо
  • +19%
пакетами по 64, workers(1)
  • неразличимо
  • неразличимо
пакетами по 64, workers(4)
  • неразличимо
  • неразличимо
пакетами по 64, workers(8)
  • неразличимо
  • +21.6%
Показать числа таблицей
СценарийСырой цикл sqlxКрейт вручнуюСервис RustStreamОверхед
по одной, workers(1)6 606 msg/s (6 534)6 498 msg/s (6 345) (неразличимо к сырому циклу)6 519 msg/s (6 489)неразличимо
по одной, workers(4)21 422 msg/s (20 667)20 365 msg/s (20 352) (неразличимо к сырому циклу)17 465 msg/s (16 553)+18.5%
по одной, workers(8)35 388 msg/s (35 358)35 013 msg/s (34 770) (неразличимо к сырому циклу)28 664 msg/s (28 526)+19%
пакетами по 64, workers(1)31 095 msg/s (30 671)30 127 msg/s (30 047) (неразличимо к сырому циклу)29 910 msg/s (29 658)неразличимо
пакетами по 64, workers(4)100 358 msg/s (94 995)96 291 msg/s (93 160) (неразличимо к сырому циклу)94 292 msg/s (93 376)неразличимо
пакетами по 64, workers(8)154 114 msg/s (153 177)154 622 msg/s (151 889) (неразличимо к сырому циклу)120 889 msg/s (119 422)+21.6%
MySQL, форма блокировки строкНасколько каждый цикл отстаёт от лучшего круга сырого цикла
  • Сырой цикл sqlx
  • Крейт вручную
  • Сервис RustStream
  • круги, от лучшего до самого медленного
  • лучший круг
  • медианный круг
  • разброс кругов
  • неразличимо

ruststream-sqlx 0.7.0 on ruststream 0.7.1, измерено 2026-10-18. Как сняты числа

по одной, workers(1)
  • неразличимо
  • +16.4%
по одной, workers(4)
  • неразличимо
  • +25.5%
по одной, workers(8)
  • неразличимо
  • +17.8%
пакетами по 64, workers(1)
  • неразличимо
  • неразличимо
пакетами по 64, workers(4)
  • неразличимо
  • неразличимо
пакетами по 64, workers(8)
  • неразличимо
  • неразличимо
Показать числа таблицей
СценарийСырой цикл sqlxКрейт вручнуюСервис RustStreamОверхед
по одной, workers(1)7 626 msg/s (7 409)6 791 msg/s (6 498) (неразличимо к сырому циклу)6 376 msg/s (6 329)+16.4%
по одной, workers(4)17 830 msg/s (16 166)16 316 msg/s (15 688) (неразличимо к сырому циклу)13 281 msg/s (13 131)+25.5%
по одной, workers(8)21 885 msg/s (21 792)19 070 msg/s (15 962) (неразличимо к сырому циклу)17 994 msg/s (17 839)+17.8%
пакетами по 64, workers(1)36 152 msg/s (35 674)35 752 msg/s (34 773) (неразличимо к сырому циклу)35 228 msg/s (35 088)неразличимо
пакетами по 64, workers(4)107 344 msg/s (107 082)102 923 msg/s (86 929) (неразличимо к сырому циклу)99 924 msg/s (95 386)неразличимо
пакетами по 64, workers(8)158 847 msg/s (132 613)147 257 msg/s (139 066) (неразличимо к сырому циклу)143 767 msg/s (120 226)неразличимо
SQLite, форма арендыНасколько каждый цикл отстаёт от лучшего круга сырого цикла
  • Сырой цикл sqlx
  • Крейт вручную
  • Сервис RustStream
  • круги, от лучшего до самого медленного
  • лучший круг
  • медианный круг
  • разброс кругов
  • неразличимо

ruststream-sqlx 0.7.0 on ruststream 0.7.1, измерено 2026-10-18. Как сняты числа

по одной, workers(1)
  • +3.3%
  • +3.3%
по одной, workers(4)
  • +4.2%
  • +63.9%
по одной, workers(8)
  • +3%
  • +65.5%
пакетами по 64, workers(1)
  • +5%
  • неразличимо
пакетами по 64, workers(4)
  • неразличимо
  • неразличимо
пакетами по 64, workers(8)
  • неразличимо
  • неразличимо
Показать числа таблицей
СценарийСырой цикл sqlxКрейт вручнуюСервис RustStreamОверхед
по одной, workers(1)14 073 msg/s (13 850)13 609 msg/s (13 565) (+3.3% к сырому циклу)13 611 msg/s (13 599)+3.3%
по одной, workers(4)14 453 msg/s (14 266)13 846 msg/s (13 728) (+4.2% к сырому циклу)5 218 msg/s (4 723)+63.9%
по одной, workers(8)14 244 msg/s (14 181)13 814 msg/s (13 733) (+3% к сырому циклу)4 916 msg/s (4 754)+65.5%
пакетами по 64, workers(1)33 167 msg/s (33 147)31 521 msg/s (31 281) (+5% к сырому циклу)33 092 msg/s (31 648)неразличимо
пакетами по 64, workers(4)34 067 msg/s (33 800)35 105 msg/s (33 255) (неразличимо к сырому циклу)34 839 msg/s (33 646)неразличимо
пакетами по 64, workers(8)35 446 msg/s (34 634)34 829 msg/s (33 519) (неразличимо к сырому циклу)35 544 msg/s (35 537)неразличимо
Postgres, путь outbox туда и обратно через Redis Pub/SubНасколько каждый цикл отстаёт от лучшего круга приложения без outbox
  • Без outbox
  • Outbox, написанный вручную
  • Outbox крейта
  • круги, от лучшего до самого медленного
  • лучший круг
  • медианный круг
  • разброс кругов
  • неразличимо

ruststream-sqlx 0.7.0 on ruststream 0.7.1, измерено 2026-10-18. Как сняты числа

по одной, workers(1)
  • +85.2%
  • +85.8% (+3.7% к ручному)
по одной, workers(4)
  • +50.8%
  • +51.9% (неразличимо к ручному)
по одной, workers(8)
  • +37.2%
  • +39.7% (+3.9% к ручному)
Показать числа таблицей
СценарийБез outboxOutbox, написанный вручнуюOutbox крейтаОверхедК outbox, написанному вручную
по одной, workers(1)54 941 msg/s (52 927)8 128 msg/s (8 097) (+85.2% к варианту без outbox)7 826 msg/s (7 663)+85.8%+3.7%
по одной, workers(4)51 743 msg/s (51 332)25 440 msg/s (25 275) (+50.8% к варианту без outbox)24 866 msg/s (24 810)+51.9%неразличимо
по одной, workers(8)50 650 msg/s (45 681)31 813 msg/s (31 242) (+37.2% к варианту без outbox)30 560 msg/s (29 582)+39.7%+3.9%

Машина​

ПроцессорAMD Ryzen 9 7900X 12-Core Processor
Архитектураx86_64
Частота427-5912 MHz
Ядра12 physical, 24 logical
Память62.4 GiB
Скорость памятиunknown
Операционная системаLinux 7.2.11-x64v3-xanmod1-1
Базы данныхpostgres:17-alpine, mysql:8.0, redis:7-alpine in Docker on the host network, without durability; SQLite bundled with sqlx, on a local file in WAL mode; the outbox over MemoryBroker in the code table and over Redis Pub/Sub in the wall clock
Круговая задержка17.4 us (median of 2000 `SELECT 1` round trips on one Postgres connection)
Компилятор1.99.0
sqlx0.9.0
Профиль сборкиbench, inheriting release (opt-level = 3, lto = fat, codegen-units = 16, debug = line-tables-only)
Фичиruststream-sqlx inbox,outbox,postgres,mysql,sqlite,chrono; ruststream macros,json,memory; ruststream-fred default
RUSTFLAGSnone (the recipe clears RUSTFLAGS, so the numbers are not tied to this CPU)
Valgrind3.25.1

Числа берутся из файла docs/benchmarks/results.json этой версии, который записывают рецепты бенчмарков, и публикуются рядом со страницами как benchmarks/results.json. Как они сняты, объясняет страница Методология, а какие выводы они позволяют сделать, - страница Числа.