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

Moving NIOPerformanceTester to use package-benchmark for additional metrics #2392

Closed
wants to merge 5 commits into from

Conversation

hassila
Copy link
Contributor

@hassila hassila commented Mar 16, 2023

Adding support for package-benchmark

Motivation:

It'd be good to get a wider range of metrics for some performance tests (e.g. UDP/TCP could provide context switches, syscalls etc) and also possibly clean up the integration testing of malloc stuff to be part of this as some of those tests seems duplicated.

This is a first stab at using package-benchmark to get feedback from the NIO team.

To get fully comparable numbers, one might want to tweak the iterations (package-benchmark uses 1K or 1M as typical iteration counts, so 100K was rounded up to 1M for these tests).

Modifications:

Added a subdirectory with a separate project (as package-benchmark depends on jemalloc) to not add any dependencies to the main swift-nio repo

Basically the code from NIOPerformanceTester is copied over and made into a library target that is used by the benchmarks, major changes is making things public so the benchmarks can see them.

main.swift has been renamed Utilities.swift and just contains the supporting setup that was top level before, all the benchmarks have been migrated to the actual benchmark executable targets
Benchmark.swift has been reduced to just define the protocols implemented by the NIO benchmarks (which are still in use to minimise the changes to the benchmarks themselves)
The benchmarks classes have been made public to be accessible by the benchmark executable targets.

The actual benchmarks are largely untouched, do a diff vs the NIOPerformanceTester target directory and the original sources for overview (I didn't want to move them, as this PR could be landed first and then the legacy NIOPerformanceTester tests could be removed in a separate PR).

Result:

Wider range of benchmark metrics, richer set of PR threshold checks (usable for e.g. liburing work to see syscalls/context switches etc), better benchmark result analytics with comparisons possible between different NIO releases, less code.
Possibility to kill the integration tests with malloc checks to something that will continuously will be updated (and possibly remove duplicated code there, as at a quick glance some of those tests are dups it seems?).

Tasks

  • Get feedback from NIO team on quality of measurements / setup
  • Define acceptable thresholds for various metrics that can be compared with check (these can basically replace the old malloc counters in the integration test suite, not sure those tests are needed anymore, they at a quick glance looks like duplicates of the NIOPerformanceTester ones?)
  • Integration with NIO build infrastructure (would need help with that) - sample GitHub workflow action
  • Try running with different NIO versions (would easiest be done by changing this package manifest to whatever version you want to test)
  • Showcase output with JMH, Delta comparisons and checks versus different versions / PR:s
  • Use wider range of metrics as required (started with e.g. UDPandTCP)
  • Review / discussion of any minor benchmark changes done (fundamentally iteration count setup)

@hassila
Copy link
Contributor Author

hassila commented Mar 16, 2023

swift package --disable-sandbox benchmark --grouping metric --metric wallClock
Detailed output
hassila@max ~/G/s/Benchmarks (03-15-Benchmark_support)> swift package --disable-sandbox benchmark --grouping metric --metric wallClock
Building for debugging...
Build complete! (0.23s)
Building benchmark targets in release mode for benchmark run...
Building WebSocket
Building UDPAndTCP
Building Miscellaneous
Building HTTPRequests
Building HTTPHeaders
Building Futures
Building ByteBuffer
Build complete!

==================
Running Benchmarks
==================

100% [------------------------------------------------------------] ETA: 00:00:00 | WebSocket:websocket_encode_50b_space_at_front_100k_frames_cow
100% [------------------------------------------------------------] ETA: 00:00:00 | WebSocket:websocket_encode_50b_space_at_front_1m_frames_cow_masking
100% [------------------------------------------------------------] ETA: 00:00:00 | ByteBuffer:bytebuffer_multi_rw_10_uint32s
...
100% [------------------------------------------------------------] ETA: 00:00:00 | ByteBuffer:bytebufferview_copy_to_array_100k_times_1kb

====================================================================================================
Baseline 'Current run'
====================================================================================================

Host 'max.local' with 10 'arm64' processors with 64 GB memory, running:
Darwin Kernel Version 22.3.0: Mon Jan 30 20:38:37 PST 2023; root:xnu-8792.81.3~2/RELEASE_ARM64_T6000

Time (wall clock)
╒════════════════════════════════════════════════════════════════════════╤══════════╤══════════╤══════════╤══════════╤══════════╤══════════╤══════════╤══════════╕
│ Test                                                                   │       p0 │      p25 │      p50 │      p75 │      p90 │      p99 │     p100 │  Samples │
╞════════════════════════════════════════════════════════════════════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╡
│ ByteBuffer:byte_buffer_view_contains_12mb (ms)                         │       31 │       32 │       32 │       32 │       32 │       33 │       33 │       16 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:byte_buffer_view_iterator_1mb (ms)                          │       13 │       13 │       13 │       13 │       13 │       13 │       13 │       38 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_lots_of_rw (ms)                                  │      240 │      240 │      240 │      245 │      245 │      245 │      245 │        3 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_multi_rw_10_uint32s (ms)                         │      679 │      680 │      680 │      680 │      680 │      680 │      680 │        1 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_rw_10_uint32s (ms)                               │      400 │      401 │      401 │      405 │      405 │      405 │      405 │        2 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_large_calculated_strings (ms)         │       76 │       76 │       77 │       77 │       77 │       77 │       77 │        7 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_medium_calculated_strings (ms)        │       48 │       48 │       48 │       48 │       48 │       48 │       48 │       11 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_medium_string_literals (ms)           │     4028 │     4030 │     4030 │     4030 │     4030 │     4030 │     4030 │        1 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_short_calculated_strings (ms)         │       49 │       50 │       50 │       50 │       51 │       53 │       53 │       10 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_short_string_literals (ms)            │       66 │       67 │       67 │       67 │       67 │       67 │       67 │        8 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_http_response_ascii_only_as_staticstring … │      915 │      915 │      915 │      915 │      915 │      915 │      915 │        1 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_http_response_ascii_only_as_string (ms)    │       17 │       17 │       17 │       17 │       17 │       18 │       18 │       29 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_http_response_some_nonascii_as_staticstri… │      895 │      896 │      896 │      896 │      896 │      896 │      896 │        1 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_http_response_some_nonascii_as_string (ms) │      870 │      871 │      871 │      871 │      871 │      871 │      871 │        1 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebufferview_copy_to_array_100k_times_1kb (μs)            │     6393 │     6483 │     6520 │     6598 │     6725 │     7458 │     7458 │       77 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_reduce_10k_futures (μs)                                 │     9289 │     9363 │     9445 │     9551 │     9994 │    10829 │    10829 │       53 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_reduce_into_10k_futures (μs)                            │     8175 │     8237 │     8278 │     8318 │     8470 │     9502 │     9502 │       60 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallcomplete_100k_deferred_on_loop (ms)              │       42 │       43 │       43 │       44 │       46 │       46 │       46 │       12 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallcomplete_100k_immediately_succeeded_off_loop (m… │       21 │       21 │       21 │       22 │       22 │       24 │       24 │       23 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallcomplete_100k_immediately_succeeded_on_loop (ms) │       21 │       22 │       22 │       22 │       23 │       24 │       24 │       23 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallcomplete_10k_deferred_off_loop (μs)              │     7000 │     7110 │     7188 │     7356 │     7618 │     8134 │     8134 │       69 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallsucceed_100k_immediately_succeeded_off_loop (ms) │       51 │       51 │       52 │       52 │       53 │       56 │       56 │       10 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallsucceed_100k_immediately_succeeded_on_loop (ms)  │       53 │       53 │       54 │       55 │       56 │       56 │       56 │       10 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallsucceed_10k_deferred_off_loop (ms)               │       11 │       11 │       11 │       11 │       12 │       12 │       12 │       43 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallsucceed_10k_deferred_on_loop (μs)                │     8167 │     8298 │     8364 │     8486 │     8716 │     9609 │     9609 │       60 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:http_headers_canonical_form (μs)                           │      707 │      710 │      714 │      721 │      740 │      791 │      805 │      694 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:http_headers_canonical_form_trimming_whitespace (μs)       │     1183 │     1188 │     1192 │     1203 │     1240 │     1297 │     1327 │      416 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:http_headers_canonical_form_trimming_whitespace_from_long… │     1665 │     1672 │     1684 │     1723 │     1772 │     1959 │     1986 │      293 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:http_headers_canonical_form_trimming_whitespace_from_shor… │     1102 │     1106 │     1111 │     1121 │     1148 │     1214 │     1230 │      447 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:write_http_headers (μs)                                    │       24 │       24 │       24 │       24 │       25 │       32 │      105 │    19913 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPRequests:http1_1k_reqs_100_conns (ms)                              │       44 │       44 │       45 │       46 │       46 │       68 │       68 │       22 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPRequests:http1_1k_reqs_1_conn (ms)                                 │       29 │       29 │       29 │       30 │       31 │       46 │       46 │       33 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPRequests:net_http1_1k_reqs_1_conn (μs)                             │     6361 │     6459 │     6488 │     6533 │     6623 │     6832 │     6868 │      154 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:asyncsequenceproducer_consume_1M_times (ms)              │      481 │      481 │      483 │      487 │      487 │      487 │      487 │        3 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:asyncwriter_single_writes_1M_times (ms)                  │      283 │      283 │      286 │      287 │      288 │      288 │      288 │        4 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:byte_to_message_decoder_decode_many_small (ms)           │       20 │       20 │       20 │       20 │       21 │       21 │       21 │       49 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:channel_pipeline_1m_events (ms)                          │       44 │       44 │       44 │       44 │       44 │       47 │       47 │       23 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:circular_buffer_into_byte_buffer_1kb (ms)                │       16 │       16 │       17 │       17 │       17 │       17 │       17 │       59 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:circular_buffer_into_byte_buffer_1mb (ms)                │       42 │       42 │       42 │       43 │       43 │       44 │       44 │       24 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:circularbuffer_copy_to_array_10k_times_1kb (ms)          │       10 │       10 │       10 │       10 │       10 │       10 │       10 │       98 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:deadline_now_1M_times (ms)                               │       12 │       13 │       13 │       13 │       13 │       13 │       13 │       75 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:execute_100k_tasks (ms)                                  │      135 │      135 │      137 │      139 │      141 │      141 │      141 │        8 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:generate_10k_random_request_keys (ms)                    │     4932 │     4936 │     4936 │     4936 │     4936 │     4936 │     4936 │        1 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:lock_1_thread_10M_ops (ms)                               │       85 │       86 │       86 │       87 │       88 │       88 │       88 │       12 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:lock_2_threads_10M_ops (ms)                              │      156 │      166 │      172 │      175 │      175 │      175 │      175 │        6 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:lock_4_threads_10M_ops (ms)                              │      189 │      192 │      198 │      209 │      218 │      218 │      218 │        5 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:lock_8_threads_10M_ops (ms)                              │      200 │      204 │      210 │      217 │      228 │      228 │      228 │        5 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:schedule_100k_tasks (ms)                                 │      117 │      118 │      118 │      118 │      120 │      120 │      120 │        9 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:schedule_and_run_100k_tasks (ms)                         │      186 │      186 │      187 │      194 │      199 │      199 │      199 │        6 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:udp_10k_writes (ms)                                      │      166 │      169 │      170 │      171 │      175 │      175 │      175 │        6 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ UDPAndTCP:tcp_100k_messages_throughput (ms)                            │      321 │      321 │      325 │      328 │      344 │      344 │      344 │        4 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ UDPAndTCP:udp_10k_vector_reads (ms)                                    │      168 │      169 │      172 │      178 │      184 │      184 │      184 │        6 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ UDPAndTCP:udp_10k_vector_reads_and_writes (ms)                         │       82 │       82 │       83 │       85 │       85 │       86 │       86 │       12 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ UDPAndTCP:udp_10k_vector_writes (ms)                                   │       82 │       83 │       83 │       87 │       88 │       88 │       88 │       12 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ UDPAndTCP:udp_10k_writes (ms)                                          │      172 │      174 │      178 │      194 │      206 │      206 │      206 │        6 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_125b_10k_frames (μs)                        │     7254 │     7331 │     7380 │     7454 │     7536 │     7929 │     7929 │       68 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_125b_with_a_masking_key_10k_frames (μs)     │     7569 │     7618 │     7663 │     7749 │     7888 │     8052 │     8052 │       65 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_64kb_+1_10k_frames (μs)                     │     7442 │     7565 │     7614 │     7684 │     7774 │     7933 │     7933 │       66 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_64kb_+1_with_a_masking_key_10k_frames (μs)  │     7663 │     7704 │     7819 │     7954 │     8077 │     8601 │     8601 │       64 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_64kb_10k_frames (μs)                        │     7499 │     7561 │     7614 │     7733 │     7815 │     7929 │     7929 │       66 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_64kb_with_a_masking_key_10k_frames (μs)     │     7708 │     7831 │     7905 │     7999 │     8142 │     9199 │     9199 │       63 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_1kb_no_space_at_front_100k_frames_cow (ms)  │       26 │       26 │       26 │       26 │       26 │       26 │       26 │       19 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_1kb_no_space_at_front_10k_frames (μs)       │     4159 │     4218 │     4276 │     4362 │     4440 │     4685 │     4825 │      117 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_1kb_space_at_front_10k_frames (μs)          │     4175 │     4214 │     4268 │     4325 │     4411 │     4562 │     4579 │      117 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_1kb_space_at_front_1m_frames_cow (ms)       │      262 │      262 │      262 │      264 │      264 │      264 │      264 │        2 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_no_space_at_front_100k_frames (ms)      │       39 │       39 │       39 │       39 │       39 │       40 │       40 │       13 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_no_space_at_front_100k_frames_cow (ms)  │       25 │       25 │       25 │       25 │       25 │       25 │       25 │       20 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_space_at_front_100k_frames (ms)         │       39 │       39 │       39 │       39 │       40 │       42 │       42 │       13 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_space_at_front_100k_frames_cow (ms)     │       24 │       25 │       25 │       25 │       25 │       25 │       25 │       20 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_space_at_front_10k_frames_masking (μs)  │     5517 │     5550 │     5586 │     5631 │     5701 │     5873 │     5873 │       90 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_space_at_front_1m_frames_cow_masking (… │      427 │      427 │      427 │      430 │      430 │      430 │      430 │        2 │
╘════════════════════════════════════════════════════════════════════════╧══════════╧══════════╧══════════╧══════════╧══════════╧══════════╧══════════╧══════════╛

@hassila
Copy link
Contributor Author

hassila commented Mar 16, 2023

UDPAndTCP:tcp_100k_messages_throughput sometimes crashes during runtime, this is the failure of the TCP benchmark:

* thread #4, queue = 'com.apple.root.default-qos.cooperative', stop reason = Swift runtime failure: Unexpectedly found nil while implicitly unwrapping an Optional value
    frame #1: 0x0000000100215998 UDPAndTCP`closure #1 in TCPThroughputBenchmark.run() at TCPThroughputBenchmark.swift:49:26 [opt]
   46  	
   47  	        public func send(_ message: ByteBuffer, times count: Int) {
   48  	            for _ in 0..<count {
-> 49  	                _ = self.channel.writeAndFlush(message.slice())


   50  	            }
   51  	        }
   52  	    }
Target 0: (UDPAndTCP) stopped.
(lldb) bt
* thread #4, queue = 'com.apple.root.default-qos.cooperative', stop reason = Swift runtime failure: Unexpectedly found nil while implicitly unwrapping an Optional value
    frame #0: 0x0000000100215998 UDPAndTCP`closure #1 in TCPThroughputBenchmark.run() [inlined] Swift runtime failure: Unexpectedly found nil while implicitly unwrapping an Optional value at TCPThroughputBenchmark.swift:0 [opt]
  * frame #1: 0x0000000100215998 UDPAndTCP`closure #1 in TCPThroughputBenchmark.run() at TCPThroughputBenchmark.swift:49:26 [opt]
    frame #2: 0x000000010021598c UDPAndTCP`closure #1 in TCPThroughputBenchmark.run(self=0x00000001022f8780) at TCPThroughputBenchmark.swift:137:32 [opt]
    frame #3: 0x0000000100215b68 UDPAndTCP`partial apply for closure #1 in TCPThroughputBenchmark.run() at <compiler-generated>:0 [opt]


    frame #4: 0x00000001000a4890 UDPAndTCP`specialized thunk for @@escaping @callee_guaranteed @@Sendable @@async () -> (@@out A) at <compiler-generated>:0 [opt]


    frame #5: 0x00000001000a6408 UDPAndTCP`partial apply for specialized thunk for escaping @callee_guaranteed Sendable async () -> (out A) at <compiler-generated>:0 [opt]


(lldb) 

Ping @ser-0xff

To debug, checkout this branch, build and run in debugger thus:

> lldb .build/arm64-apple-macosx/release/UDPAndTCP


(lldb) target create ".build/arm64-apple-macosx/release/UDPAndTCP"
Current executable set to '/Users/hassila/GitHub/swift-nio/Benchmarks/.build/arm64-apple-macosx/release/UDPAndTCP' (arm64).
(lldb) run --filter tcp_100k_messages_throughput

(I have only seen the crash with the optimised build, couldn't repro with debug build)

@hassila hassila mentioned this pull request Mar 16, 2023
7 tasks
@hassila hassila marked this pull request as draft March 16, 2023 08:02
Copy link
Member

@FranzBusch FranzBusch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for opening this. I haven't looked through all of the code yet but have some questions.

  1. You brought over the NIOPerformanceTester scaffolding to avoid code churn. Is this also the recommended way you think we should write Benchmarks with your package or how would you recommend we implement them if we would start from scratch?
  2. How consistent are the results of the benchmark (Disregarding the time for now and only looking at malloc and sys calls)?
  3. I am still a bit unsure about the combination of @main & @dynamicReplacement together. Couldn't we just make the user provide a struct that inherits from a protocol which is marked with @main and provides the static func main?

Will read a bit more through the code!

@Lukasa
Copy link
Contributor

Lukasa commented Mar 16, 2023

Yes, almost all the allocation counter tests would be able to be replaced as they're largely dupes. check is a good source. The limits are present in environment variables, so a useful initial step would be to obtain those limits from there.

@hassila
Copy link
Contributor Author

hassila commented Mar 16, 2023

Thanks for opening this. I haven't looked through all of the code yet but have some questions.

  1. You brought over the NIOPerformanceTester scaffolding to avoid code churn. Is this also the recommended way you think we should write Benchmarks with your package or how would you recommend we implement them if we would start from scratch?

I think the cleanest approach for smaller benchmarks would simply be something like:

    Benchmark("bytebuffer_write_12MB_short_string_literals") { benchmark in
        let bufferSize = 12 * 1024 * 1024
        var buffer = ByteBufferAllocator().buffer(capacity: bufferSize)

       benchmark.startMeasurement() // optional, but let's say we want to have a test setup, the code above this line will not be counted towards in terms of metrics, if not called all the preamble will be part of the measurement

        for _ in 0 ..< 3 {
            buffer.clear()
            for _ in 0 ..< (bufferSize / 4) {
                buffer.writeString("abcd")
            }
        }

        let readableBytes = buffer.readableBytes
        precondition(readableBytes == bufferSize)
        blackHole(readableBytes)
       benchmark.stopMeasurement() // optional, only needed if we would have some teardown code that we don't want to be part of an measurement
     // teardown code goes here
    }

So for clean tests with no specific setup/teardown (or where they are such a small part of the runtime they don't matter), you don't need to use start/stop measurement and it will be done for the scope implicitly (thus avoiding boilerplate for most cases).

This is for handling setup/teardown per iteration of the test, if you would have setup/teardown that you want to be done only a single time for multiple iterations, you can use benchmarks startup/shutdown hooks

For the existing NIOPerformanceTester classes / tests, I'd probably move them over to their respective benchmark target instead and remove the shared target as they are fundamentally freestanding - then the current NIOPerformanceTester:Benchmark.swift protocols could be dropped completely also and just use the measurement start/stop hooks outlined above when needed instead.

It's really the same trade off you would have when writing a unit test, as long as the suite is short enough and the tests are short enough, I'd just inline as above personally, but for more complicated tests I'd break them out into separate files and just call setup/teardown if needed as outlined above.

  1. How consistent are the results of the benchmark (Disregarding the time for now and only looking at malloc and sys calls)?

Malloc and syscalls should be stable across runs (if the benchmark behaves consistently) and should be suited for regression checks using swift package benchmark check. Time is as you imply always difficult unless you have a dedicated machine (and preferably a dedicated processor set with pinned threads, if you want to be really careful) - but a dedicated machine and focusing on appropriate deviations per percentile goes a long way in practice (much more useful than standard deviations and averages in our experience, as we can apply similar threshold both for latency oriented tests and throughput oriented tests).

  1. I am still a bit unsure about the combination of @main & @dynamicReplacement together. Couldn't we just make the user provide a struct that inherits from a protocol which is marked with @main and provides the static func main?

Yeah, I haven't gotten it to work, as the underlying benchmark infrastructure uses Swift Argument Parser which needs to handle the main entry point, I've done two tries to make that work and so far failed both times... The root problem then always comes back to that there's no way (except @dynamicReplacement) AFAIK for a library target to find and call an entry point in a hosting application (by design AFAIU). I don't love @dynamicReplacement, but I do love SAP and would like to be able to use it and not hand roll all that functionality...

@hassila
Copy link
Contributor Author

hassila commented Mar 16, 2023

Yes, almost all the allocation counter tests would be able to be replaced as they're largely dupes.

That'd be nice, then we could also get syscall / context switch tests and similar easily if desired.

check is a good source. The limits are present in environment variables, so a useful initial step would be to obtain those limits from there.

I'll have a look at how the current test runs and existing allocation counters match up - it's worth reiterating that the approach taken by Benchmark is fundamentally different though from the current approach (with manually hard coded thresholds);

The overall idea is that as a check for a PR, we should measure mallocs (or other metrics) first for main, then for the PR, then we compare the results with whatever thresholds we have specified (either absolute, relative or both) vs main.

This means that improvements to any measured metric will be allowed and will automatically be the new baseline for the metric, as any future PR would be compared to that improved metric. This also means no manual management of threshold is required.

Concretely, we could say that for the number of allocations metrics, there is a zero regression policy (absolute difference 0) for p99 for example.

@hassila
Copy link
Contributor Author

hassila commented Mar 16, 2023

Wrt to malloc/syscall stability, I'd amend that and say that sometimes we can see slightly off p0/p100, but we usually don't have those as part of our defined thresholds, or at least allow for more slack (especially for p100). It also can be that some tests get bi- or multi-modal and then will give a wide range of measurements - I for fun just run the malloc counters for the existing PR and most are quite stable across runs, but a few of the tests vary between e.g. p25 and p99, likely due to multi-modality or concurrency aspects of the test.

swift package --disable-sandbox benchmark --grouping metric --metric mallocCountTotal --skip tcp_100k_messages_throughput
Detailed output
Malloc (total)
╒════════════════════════════════════════════════════════════════════════╤══════════╤══════════╤══════════╤══════════╤══════════╤══════════╤══════════╤══════════╕
│ Test                                                                   │       p0 │      p25 │      p50 │      p75 │      p90 │      p99 │     p100 │  Samples │
╞════════════════════════════════════════════════════════════════════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╡
│ ByteBuffer:byte_buffer_view_contains_12mb                              │        0 │        0 │        0 │        0 │        0 │        0 │        0 │       30 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:byte_buffer_view_iterator_1mb                               │        0 │        0 │        0 │        0 │        0 │        0 │        0 │       74 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_lots_of_rw (K)                                   │      999 │     1000 │     1000 │     1000 │     1000 │     1000 │     1000 │        4 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_multi_rw_10_uint32s                              │       20 │       20 │       20 │       22 │       22 │       22 │       22 │        2 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_rw_10_uint32s                                    │       16 │       16 │       16 │       26 │       26 │       26 │       26 │        3 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_large_calculated_strings              │       18 │       18 │       18 │       18 │       18 │       21 │       21 │       13 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_medium_calculated_strings             │        3 │        3 │        3 │        3 │        3 │        6 │        6 │       20 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_medium_string_literals                │        2 │        2 │        2 │        2 │        2 │        2 │        4 │      194 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_short_calculated_strings              │        2 │        2 │        2 │        2 │        2 │        5 │        5 │       20 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_short_string_literals                 │        2 │        2 │        2 │        2 │        2 │        4 │        4 │       15 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_http_response_ascii_only_as_staticstring   │        2 │        2 │        2 │        4 │        4 │        4 │        4 │        2 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_http_response_ascii_only_as_string         │        2 │        2 │        2 │        2 │        2 │        2 │        4 │     1104 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_http_response_some_nonascii_as_staticstri… │        2 │        2 │        2 │        4 │        4 │        4 │        4 │        2 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_http_response_some_nonascii_as_string      │        2 │        2 │        2 │        4 │        4 │        4 │        4 │        2 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebufferview_copy_to_array_100k_times_1kb (K)             │       99 │      100 │      100 │      100 │      100 │      100 │      100 │      147 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_reduce_10k_futures (K)                                  │       54 │       82 │       94 │       94 │       94 │       94 │       94 │       99 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_reduce_into_10k_futures (K)                             │       74 │       84 │       84 │       86 │      103 │      103 │      103 │      113 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallcomplete_100k_deferred_on_loop (K)               │      299 │      300 │      300 │      300 │      300 │      300 │      300 │       22 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallcomplete_100k_immediately_succeeded_off_loop (K) │       99 │      100 │      100 │      100 │      100 │      100 │      100 │       44 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallcomplete_100k_immediately_succeeded_on_loop (K)  │       99 │      100 │      100 │      100 │      100 │      100 │      100 │       41 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallcomplete_10k_deferred_off_loop (K)               │       40 │       40 │       40 │       40 │       40 │       40 │       40 │      130 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallsucceed_100k_immediately_succeeded_off_loop (K)  │      356 │      356 │      356 │      356 │      356 │      357 │      357 │       18 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallsucceed_100k_immediately_succeeded_on_loop (K)   │      499 │      500 │      500 │      500 │      500 │      500 │      500 │       18 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallsucceed_10k_deferred_off_loop (K)                │       60 │       60 │       70 │       79 │       79 │       80 │       80 │       79 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallsucceed_10k_deferred_on_loop (K)                 │       50 │       60 │       60 │       70 │       70 │       70 │       80 │      109 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:http_headers_canonical_form                                │        7 │        7 │        7 │        7 │        7 │        7 │       11 │    38196 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:http_headers_canonical_form_trimming_whitespace            │        7 │        7 │        7 │        7 │        7 │        7 │       11 │    37058 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:http_headers_canonical_form_trimming_whitespace_from_long… │        7 │        7 │        7 │        7 │        7 │        7 │       11 │    36392 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:http_headers_canonical_form_trimming_whitespace_from_shor… │        7 │        7 │        7 │        7 │        7 │        7 │       11 │    37846 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:write_http_headers                                         │        4 │        4 │        4 │        4 │        4 │        4 │       11 │    37699 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPRequests:http1_1k_reqs_100_conns (K)                               │        9 │       21 │       30 │       47 │       97 │      103 │      103 │       19 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPRequests:http1_1k_reqs_1_conn (K)                                  │        7 │       10 │       15 │       22 │       22 │       23 │       23 │       27 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPRequests:net_http1_1k_reqs_1_conn (K)                              │       31 │       31 │       31 │       31 │       31 │       31 │       31 │      148 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:asyncsequenceproducer_consume_1M_times                   │        4 │        4 │        4 │       56 │       56 │       56 │       56 │        2 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:asyncwriter_single_writes_1M_times (K)                   │      999 │     1000 │     1000 │     1000 │     1000 │     1000 │     1000 │        4 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:byte_to_message_decoder_decode_many_small                │        0 │        0 │        0 │        0 │        0 │        2 │        2 │       47 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:channel_pipeline_1m_events                               │        0 │        0 │        0 │        0 │        0 │        0 │        0 │       22 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:circular_buffer_into_byte_buffer_1kb                     │        0 │        0 │        0 │        0 │        0 │        0 │        0 │       57 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:circular_buffer_into_byte_buffer_1mb                     │        0 │        0 │        0 │        0 │        0 │        0 │        0 │       23 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:circularbuffer_copy_to_array_10k_times_1kb (K)           │       10 │       10 │       10 │       10 │       10 │       10 │       10 │       94 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:deadline_now_1M_times                                    │        0 │        0 │        0 │        0 │        0 │        0 │        0 │       70 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:execute_100k_tasks                                       │       23 │       23 │       23 │       23 │       71 │       71 │       71 │        7 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:generate_10k_random_request_keys (K)                     │       30 │       30 │       30 │       30 │       30 │       30 │       30 │      190 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:lock_1_thread_10M_ops                                    │        4 │        4 │        4 │        4 │        4 │        5 │        5 │       12 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:lock_2_threads_10M_ops                                   │        8 │        8 │        8 │        8 │        9 │        9 │        9 │        7 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:lock_4_threads_10M_ops                                   │       16 │       16 │       16 │       16 │       17 │       17 │       17 │        5 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:lock_8_threads_10M_ops                                   │       32 │       32 │       32 │       32 │       33 │       33 │       33 │        5 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:schedule_100k_tasks (K)                                  │      399 │      400 │      400 │      400 │      400 │      400 │      400 │        8 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:schedule_and_run_100k_tasks (K)                          │      399 │      400 │      400 │      400 │      400 │      400 │      400 │        5 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:udp_10k_writes (K)                                       │       29 │       29 │       29 │       29 │       29 │       29 │       29 │        5 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ UDPAndTCP:udp_10k_vector_reads (K)                                     │       29 │       29 │       29 │       29 │       30 │       30 │       30 │        5 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ UDPAndTCP:udp_10k_vector_reads_and_writes (K)                          │       28 │       28 │       28 │       28 │       28 │       28 │       28 │       10 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ UDPAndTCP:udp_10k_vector_writes (K)                                    │       28 │       28 │       28 │       28 │       28 │       28 │       28 │       10 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ UDPAndTCP:udp_10k_writes (K)                                           │       29 │       29 │       29 │       29 │       30 │       30 │       30 │        5 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_125b_10k_frames (K)                         │       20 │       20 │       20 │       20 │       20 │       20 │       20 │      128 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_125b_with_a_masking_key_10k_frames (K)      │       20 │       20 │       20 │       20 │       20 │       20 │       20 │      125 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_64kb_+1_10k_frames (K)                      │       20 │       20 │       20 │       20 │       20 │       20 │       20 │      126 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_64kb_+1_with_a_masking_key_10k_frames (K)   │       20 │       20 │       20 │       20 │       20 │       20 │       20 │      124 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_64kb_10k_frames (K)                         │       20 │       20 │       20 │       20 │       20 │       20 │       20 │      120 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_64kb_with_a_masking_key_10k_frames (K)      │       20 │       20 │       20 │       20 │       20 │       20 │       20 │      124 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_1kb_no_space_at_front_100k_frames_cow       │        0 │        0 │        0 │        0 │        0 │        2 │        2 │       36 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_1kb_no_space_at_front_10k_frames (K)        │       30 │       30 │       30 │       30 │       30 │       30 │       30 │      224 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_1kb_space_at_front_10k_frames (K)           │       30 │       30 │       30 │       30 │       30 │       30 │       30 │      221 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_1kb_space_at_front_1m_frames_cow            │        0 │        0 │        0 │        0 │        2 │        2 │        2 │        4 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_no_space_at_front_100k_frames (K)       │      299 │      300 │      300 │      300 │      300 │      300 │      300 │       25 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_no_space_at_front_100k_frames_cow       │        0 │        0 │        0 │        0 │        0 │        2 │        2 │       37 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_space_at_front_100k_frames (K)          │      299 │      300 │      300 │      300 │      300 │      300 │      300 │       25 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_space_at_front_100k_frames_cow          │        0 │        0 │        0 │        0 │        0 │        2 │        2 │       38 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_space_at_front_10k_frames_masking (K)   │       49 │       50 │       50 │       50 │       50 │       50 │       50 │      169 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_space_at_front_1m_frames_cow_masking (… │     1999 │     2000 │     2000 │     2000 │     2000 │     2000 │     2000 │        3 │
╘════════════════════════════════════════════════════════════════════════╧══════════╧══════════╧══════════╧══════════╧══════════╧══════════╧══════════╧══════════╛

@hassila
Copy link
Contributor Author

hassila commented Mar 16, 2023

And for syscalls:

swift package --disable-sandbox benchmark --grouping metric --metric syscalls --skip tcp_100k_messages_throughput
Syscalls details
Host 'ice.local' with 20 'arm64' processors with 128 GB memory, running:
Darwin Kernel Version 22.3.0: Mon Jan 30 20:38:37 PST 2023; root:xnu-8792.81.3~2/RELEASE_ARM64_T6000

Syscalls (total)
╒════════════════════════════════════════════════════════════════════════╤══════════╤══════════╤══════════╤══════════╤══════════╤══════════╤══════════╤══════════╕
│ Test                                                                   │       p0 │      p25 │      p50 │      p75 │      p90 │      p99 │     p100 │  Samples │
╞════════════════════════════════════════════════════════════════════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╡
│ ByteBuffer:byte_buffer_view_contains_12mb                              │        1 │        1 │        1 │        1 │        1 │        1 │        1 │       31 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:byte_buffer_view_iterator_1mb                               │        1 │        1 │        1 │        1 │        1 │        1 │        1 │       75 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_lots_of_rw                                       │        3 │        3 │        3 │        3 │        4 │        4 │        4 │        4 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_multi_rw_10_uint32s                              │       12 │       12 │       12 │       29 │       29 │       29 │       29 │        2 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_rw_10_uint32s                                    │        3 │        3 │        3 │       27 │       27 │       27 │       27 │        3 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_large_calculated_strings              │        3 │        3 │        3 │        3 │        3 │       22 │       22 │       13 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_medium_calculated_strings             │        3 │        3 │        3 │        3 │        3 │        4 │        4 │       21 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_medium_string_literals                │        3 │        3 │        3 │        3 │        3 │        3 │        4 │      201 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_short_calculated_strings              │        3 │        3 │        3 │        3 │        3 │        4 │        4 │       20 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_short_string_literals                 │        3 │        3 │        3 │        3 │        3 │        8 │        8 │       15 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_http_response_ascii_only_as_staticstring   │        1 │        1 │        1 │        1 │        1 │        1 │        1 │        2 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_http_response_ascii_only_as_string         │        1 │        1 │        1 │        1 │        1 │        1 │        1 │     1161 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_http_response_some_nonascii_as_staticstri… │        1 │        1 │        1 │        1 │        1 │        1 │        1 │        2 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_http_response_some_nonascii_as_string      │        1 │        1 │        1 │        1 │        1 │        1 │        1 │        2 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebufferview_copy_to_array_100k_times_1kb                 │        1 │        1 │        1 │        1 │        1 │        1 │        1 │      152 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_reduce_10k_futures                                      │        5 │        5 │        5 │        5 │        5 │        7 │      482 │      106 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_reduce_into_10k_futures                                 │        5 │        5 │        5 │        5 │        5 │        9 │      482 │      119 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallcomplete_100k_deferred_on_loop                   │      185 │      496 │      565 │      571 │      574 │     1067 │     1067 │       24 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallcomplete_100k_immediately_succeeded_off_loop     │        5 │        5 │        5 │        5 │        6 │      577 │      577 │       46 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallcomplete_100k_immediately_succeeded_on_loop      │        5 │       91 │       91 │      105 │      105 │      580 │      580 │       44 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallcomplete_10k_deferred_off_loop                   │        7 │       11 │       11 │       11 │       61 │       64 │      550 │      139 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallsucceed_100k_immediately_succeeded_off_loop      │        7 │        7 │        7 │        8 │       86 │      577 │      577 │       19 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallsucceed_100k_immediately_succeeded_on_loop       │      106 │      106 │      106 │      106 │      106 │      587 │      587 │       19 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallsucceed_10k_deferred_off_loop                    │        7 │        9 │        9 │       11 │       29 │      521 │      521 │       85 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallsucceed_10k_deferred_on_loop                     │        5 │        5 │        5 │        5 │       26 │       26 │      506 │      119 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:http_headers_canonical_form                                │        1 │        1 │        1 │        1 │        1 │        1 │        1 │   364334 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:http_headers_canonical_form_trimming_whitespace            │        1 │        1 │        1 │        1 │        1 │        1 │        1 │   305507 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:http_headers_canonical_form_trimming_whitespace_from_long… │        1 │        1 │        1 │        1 │        1 │        1 │        1 │   263265 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:http_headers_canonical_form_trimming_whitespace_from_shor… │        1 │        1 │        1 │        1 │        1 │        1 │        1 │   312805 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:write_http_headers                                         │        1 │        1 │        1 │        1 │        1 │        1 │        1 │   325094 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPRequests:http1_1k_reqs_100_conns (K)                               │       11 │       11 │       11 │       11 │       11 │       12 │       12 │       20 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPRequests:http1_1k_reqs_1_conn                                      │     6048 │     6059 │     6063 │     6075 │     6083 │     6623 │     6623 │       31 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPRequests:net_http1_1k_reqs_1_conn                                  │        1 │        1 │        1 │        1 │        1 │        1 │        2 │      153 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:asyncsequenceproducer_consume_1M_times                   │        1 │        1 │        1 │        6 │        6 │        6 │        6 │        3 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:asyncwriter_single_writes_1M_times                       │        1 │        1 │        1 │        1 │        2 │        2 │        2 │        4 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:byte_to_message_decoder_decode_many_small                │        1 │        1 │        1 │        1 │        1 │        1 │        1 │       49 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:channel_pipeline_1m_events                               │        1 │        1 │        1 │        1 │        1 │        1 │        1 │       23 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:circular_buffer_into_byte_buffer_1kb                     │        1 │        1 │        1 │        1 │        1 │        1 │        1 │       58 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:circular_buffer_into_byte_buffer_1mb                     │        1 │        1 │        1 │        1 │        1 │        1 │        1 │       23 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:circularbuffer_copy_to_array_10k_times_1kb               │        1 │        1 │        1 │        1 │        1 │        1 │        1 │       97 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:deadline_now_1M_times                                    │        1 │        1 │        1 │        1 │        1 │        1 │        1 │       74 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:execute_100k_tasks                                       │        7 │        8 │        8 │        9 │        9 │        9 │        9 │        8 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:generate_10k_random_request_keys                         │        1 │        1 │        1 │        1 │        1 │        3 │        3 │      199 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:lock_1_thread_10M_ops                                    │       11 │       11 │       12 │       12 │       12 │       12 │       12 │       12 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:lock_2_threads_10M_ops (K)                               │      100 │      103 │      109 │      122 │      123 │      123 │      123 │        7 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:lock_4_threads_10M_ops (K)                               │      211 │      221 │      231 │      247 │      250 │      250 │      250 │        5 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:lock_8_threads_10M_ops (K)                               │      126 │      135 │      138 │      157 │      170 │      170 │      170 │        5 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:schedule_100k_tasks                                      │      217 │      219 │      219 │      222 │      223 │      223 │      223 │        9 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:schedule_and_run_100k_tasks                              │      218 │      220 │      220 │      223 │      224 │      224 │      224 │        6 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:udp_10k_writes (K)                                       │       80 │       80 │       80 │       80 │       80 │       80 │       80 │        5 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ UDPAndTCP:udp_10k_vector_reads (K)                                     │       80 │       80 │       80 │       80 │       80 │       80 │       80 │        6 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ UDPAndTCP:udp_10k_vector_reads_and_writes (K)                          │       46 │       47 │       47 │       47 │       47 │       47 │       47 │       10 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ UDPAndTCP:udp_10k_vector_writes (K)                                    │       46 │       47 │       47 │       47 │       47 │       47 │       47 │       12 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ UDPAndTCP:udp_10k_writes (K)                                           │       80 │       80 │       80 │       80 │       80 │       80 │       80 │        5 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_125b_10k_frames                             │        1 │        1 │        1 │        1 │        1 │        1 │        1 │      134 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_125b_with_a_masking_key_10k_frames          │        1 │        1 │        1 │        1 │        1 │        1 │        1 │      128 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_64kb_+1_10k_frames                          │        1 │        1 │        1 │        1 │        1 │        1 │        1 │      131 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_64kb_+1_with_a_masking_key_10k_frames       │        1 │        1 │        1 │        1 │        1 │        1 │        1 │      125 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_64kb_10k_frames                             │        1 │        1 │        1 │        1 │        1 │        1 │        1 │      132 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_64kb_with_a_masking_key_10k_frames          │        1 │        1 │        1 │        1 │        1 │        1 │        1 │      129 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_1kb_no_space_at_front_100k_frames_cow       │        1 │        1 │        1 │        1 │        1 │        1 │        1 │       38 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_1kb_no_space_at_front_10k_frames            │        1 │        1 │        1 │        1 │        1 │        1 │        1 │      237 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_1kb_space_at_front_10k_frames               │        1 │        1 │        1 │        1 │        1 │        1 │        1 │      236 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_1kb_space_at_front_1m_frames_cow            │        1 │        1 │        1 │        1 │        1 │        1 │        1 │        4 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_no_space_at_front_100k_frames           │        1 │        1 │        1 │        1 │        1 │        1 │        1 │       26 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_no_space_at_front_100k_frames_cow       │        1 │        1 │        1 │        1 │        1 │        1 │        1 │       39 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_space_at_front_100k_frames              │        1 │        1 │        1 │        1 │        1 │        1 │        1 │       26 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_space_at_front_100k_frames_cow          │        1 │        1 │        1 │        1 │        1 │        1 │        1 │       39 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_space_at_front_10k_frames_masking       │        1 │        1 │        1 │        1 │        1 │        1 │        1 │      178 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_space_at_front_1m_frames_cow_masking    │        1 │        1 │        1 │        1 │        1 │        1 │        1 │        3 │
╘════════════════════════════════════════════════════════════════════════╧══════════╧══════════╧══════════╧══════════╧══════════╧══════════╧══════════╧══════════╛

</details>
  

@hassila
Copy link
Contributor Author

hassila commented Mar 16, 2023

And finally memory allocated details:

Bytes allocated
Memory (allocated)
╒════════════════════════════════════════════════════════════════════════╤══════════╤══════════╤══════════╤══════════╤══════════╤══════════╤══════════╤══════════╕
│ Test                                                                   │       p0 │      p25 │      p50 │      p75 │      p90 │      p99 │     p100 │  Samples │
╞════════════════════════════════════════════════════════════════════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╪══════════╡
│ ByteBuffer:byte_buffer_view_contains_12mb (M)                          │       24 │       24 │       24 │       24 │       24 │       24 │       24 │       31 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:byte_buffer_view_iterator_1mb (K)                           │     9830 │     9838 │     9838 │     9838 │     9838 │     9838 │     9838 │       76 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_lots_of_rw (K)                                   │     7536 │     7540 │     7540 │     7540 │     7540 │     7540 │     7540 │        4 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_multi_rw_10_uint32s (M)                          │       74 │       75 │       75 │       75 │       75 │       75 │       75 │        2 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_rw_10_uint32s (M)                                │       11 │       11 │       11 │       12 │       12 │       12 │       12 │        3 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_large_calculated_strings (M)          │       11 │       11 │       11 │       11 │       11 │       11 │       11 │       13 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_medium_calculated_strings (K)         │     7536 │     7540 │     7540 │     7540 │     7655 │     7655 │     7655 │       21 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_medium_string_literals (K)            │     7536 │     7540 │     7540 │     7540 │     7655 │     7655 │     7655 │      205 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_short_calculated_strings (K)          │     7536 │     7540 │     7540 │     7540 │     7540 │     7540 │     7540 │       21 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_12MB_short_string_literals (K)             │     7536 │     7540 │     7540 │     7540 │     7655 │     7655 │     7655 │       15 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_http_response_ascii_only_as_staticstring … │     7438 │     7442 │     7442 │     7557 │     7557 │     7557 │     7557 │        2 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_http_response_ascii_only_as_string (K)     │     7438 │     7442 │     7557 │     7557 │     7557 │     7557 │     7557 │     1145 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_http_response_some_nonascii_as_staticstri… │     7438 │     7442 │     7442 │     7557 │     7557 │     7557 │     7557 │        2 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebuffer_write_http_response_some_nonascii_as_string (K)  │     7438 │     7442 │     7442 │     7557 │     7557 │     7557 │     7557 │        2 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ ByteBuffer:bytebufferview_copy_to_array_100k_times_1kb (K)             │     7438 │     7442 │     7442 │     7442 │     7557 │     7557 │     7557 │      153 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_reduce_10k_futures (M)                                  │       23 │       23 │       23 │       23 │       23 │       23 │       23 │      104 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_reduce_into_10k_futures (M)                             │       23 │       23 │       23 │       23 │       23 │       23 │       23 │      116 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallcomplete_100k_deferred_on_loop (M)               │       37 │       40 │       97 │      177 │      214 │      239 │      239 │       24 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallcomplete_100k_immediately_succeeded_off_loop (M) │       34 │       39 │       39 │       39 │       39 │       39 │       39 │       46 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallcomplete_100k_immediately_succeeded_on_loop (M)  │       34 │       56 │       87 │      184 │      241 │      249 │      249 │       45 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallcomplete_10k_deferred_off_loop (M)               │       27 │       57 │       58 │       58 │       58 │       58 │       58 │      136 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallsucceed_100k_immediately_succeeded_off_loop (M)  │       27 │       43 │       48 │       53 │       56 │       57 │       57 │       19 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallsucceed_100k_immediately_succeeded_on_loop (M)   │       27 │       39 │       54 │       70 │       79 │       82 │       82 │       19 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallsucceed_10k_deferred_off_loop (M)                │       28 │       69 │       69 │       69 │       69 │       69 │       69 │       84 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Futures:future_whenallsucceed_10k_deferred_on_loop (M)                 │       25 │       53 │       53 │       53 │       54 │       54 │       54 │      115 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:http_headers_canonical_form (K)                            │     7438 │     7442 │     7442 │     7442 │     7557 │     7557 │     7557 │    39556 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:http_headers_canonical_form_trimming_whitespace (K)        │     7438 │     7442 │     7442 │     7442 │     7557 │     7557 │     7557 │    38974 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:http_headers_canonical_form_trimming_whitespace_from_long… │     7438 │     7442 │     7442 │     7557 │     7557 │     7557 │     7557 │    38134 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:http_headers_canonical_form_trimming_whitespace_from_shor… │     7438 │     7442 │     7442 │     7557 │     7557 │     7557 │     7557 │    39149 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPHeaders:write_http_headers (K)                                     │     7438 │     7442 │     7442 │     7442 │     7557 │     7557 │     7557 │    39411 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPRequests:http1_1k_reqs_100_conns (M)                               │       40 │       41 │       42 │       42 │       42 │       42 │       42 │       21 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPRequests:http1_1k_reqs_1_conn (M)                                  │       25 │       35 │       40 │       41 │       41 │       41 │       41 │       32 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ HTTPRequests:net_http1_1k_reqs_1_conn (K)                              │     7438 │     7442 │     7442 │     7442 │     7557 │     7557 │     7557 │      154 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:asyncsequenceproducer_consume_1M_times (K)               │     8568 │     8577 │     9232 │     9232 │     9232 │     9232 │     9232 │        3 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:asyncwriter_single_writes_1M_times (K)                   │     8044 │     8048 │     8146 │     8146 │     8146 │     8146 │     8146 │        4 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:byte_to_message_decoder_decode_many_small (K)            │     7520 │     7524 │     7524 │     7524 │     7524 │     7524 │     7524 │       47 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:channel_pipeline_1m_events (K)                           │     7438 │     7442 │     7442 │     7442 │     7442 │     7442 │     7442 │       23 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:circular_buffer_into_byte_buffer_1kb (K)                 │     7438 │     7442 │     7442 │     7524 │     7524 │     7524 │     7524 │       59 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:circular_buffer_into_byte_buffer_1mb (M)                 │       16 │       16 │       16 │       16 │       16 │       16 │       16 │       23 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:circularbuffer_copy_to_array_10k_times_1kb (K)           │     7438 │     7442 │     7442 │     7442 │     7557 │     7557 │     7557 │       98 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:deadline_now_1M_times (K)                                │     7438 │     7442 │     7442 │     7442 │     7557 │     7557 │     7557 │       74 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:execute_100k_tasks (M)                                   │       24 │       49 │       91 │      132 │      174 │      174 │      174 │        8 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:generate_10k_random_request_keys (K)                     │     7438 │     7442 │     7442 │     7442 │     7442 │     7442 │     7442 │      198 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:lock_1_thread_10M_ops (K)                                │     8667 │     9478 │     9494 │     9494 │     9609 │     9609 │     9609 │       12 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:lock_2_threads_10M_ops (K)                               │     8962 │     9543 │     9838 │     9838 │     9838 │     9838 │     9838 │        7 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:lock_4_threads_10M_ops (M)                               │        9 │       10 │       10 │       10 │       10 │       10 │       10 │        5 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:lock_8_threads_10M_ops (M)                               │       10 │       11 │       11 │       11 │       11 │       11 │       11 │        5 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:schedule_100k_tasks (M)                                  │       32 │       82 │      132 │      182 │      232 │      232 │      232 │        9 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:schedule_and_run_100k_tasks (M)                          │       32 │       57 │       82 │      132 │      157 │      157 │      157 │        6 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ Miscellaneous:udp_10k_writes (M)                                       │        8 │        9 │       10 │       11 │       12 │       12 │       12 │        6 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ UDPAndTCP:udp_10k_vector_reads (M)                                     │        8 │        9 │       10 │       11 │       12 │       12 │       12 │        6 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ UDPAndTCP:udp_10k_vector_reads_and_writes (M)                          │        9 │       11 │       16 │       20 │       22 │       24 │       24 │       12 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ UDPAndTCP:udp_10k_vector_writes (M)                                    │        9 │       11 │       16 │       20 │       22 │       24 │       24 │       12 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ UDPAndTCP:udp_10k_writes (M)                                           │        8 │        9 │       10 │       11 │       12 │       12 │       12 │        6 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_125b_10k_frames (K)                         │     7438 │     7442 │     7442 │     7442 │     7786 │     7786 │     7786 │      136 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_125b_with_a_masking_key_10k_frames (K)      │     7438 │     7442 │     7442 │     7442 │     7671 │     7671 │     7671 │      133 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_64kb_+1_10k_frames (K)                      │     7585 │     7589 │     7589 │     7589 │     7589 │     7589 │     7589 │      133 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_64kb_+1_with_a_masking_key_10k_frames (K)   │     7585 │     7589 │     7589 │     7589 │     7589 │     7589 │     7589 │      130 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_64kb_10k_frames (K)                         │     7585 │     7589 │     7589 │     7589 │     7704 │     7704 │     7704 │      133 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_decode_64kb_with_a_masking_key_10k_frames (K)      │     7585 │     7589 │     7589 │     7589 │     7589 │     7589 │     7589 │      130 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_1kb_no_space_at_front_100k_frames_cow (K)   │     7438 │     7442 │     7442 │     7442 │     7557 │     7557 │     7557 │       37 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_1kb_no_space_at_front_10k_frames (K)        │     7438 │     7442 │     7442 │     7442 │     7557 │     7557 │     7557 │      235 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_1kb_space_at_front_10k_frames (K)           │     7438 │     7442 │     7442 │     7442 │     7671 │     7671 │     7671 │      235 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_1kb_space_at_front_1m_frames_cow (K)        │     7438 │     7442 │     7442 │     7442 │     7557 │     7557 │     7557 │        4 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_no_space_at_front_100k_frames (K)       │     7438 │     7442 │     7442 │     7442 │     7557 │     7557 │     7557 │       26 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_no_space_at_front_100k_frames_cow (K)   │     7438 │     7442 │     7442 │     7442 │     7671 │     7671 │     7671 │       40 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_space_at_front_100k_frames (K)          │     7438 │     7442 │     7442 │     7442 │     7557 │     7557 │     7557 │       26 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_space_at_front_100k_frames_cow (K)      │     7438 │     7442 │     7442 │     7442 │     7671 │     7671 │     7671 │       39 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_space_at_front_10k_frames_masking (K)   │     7438 │     7442 │     7442 │     7442 │     7671 │     7671 │     7671 │      177 │
├────────────────────────────────────────────────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
│ WebSocket:websocket_encode_50b_space_at_front_1m_frames_cow_masking (… │     7438 │     7442 │     7442 │     7557 │     7557 │     7557 │     7557 │        3 │
╘════════════════════════════════════════════════════════════════════════╧══════════╧══════════╧══════════╧══════════╧══════════╧══════════╧══════════╧══════════╛

@FranzBusch
Copy link
Member

That's all really great @hassila. Thanks for expanding on the questions!

I think we have one requirement though which is making the thresholds come through the env vars because we know that different Swift versions have different thresholds due to language improvements and sometimes regressions.

I would like to talk about how we could potentially land this. IMO moving the whole thing over at once isn't the best approach. What I think we should do is land them step by step and refactor them on the way to match how your package expects benchmarks to be written. This way we can run them in parallel and also make the PRs more digestible. We also some internal things to figure out.

Yeah, I haven't gotten it to work, as the underlying benchmark infrastructure uses Swift Argument Parser which needs to handle the main entry point, I've done two tries to make that work and so far failed both times... The root problem then always comes back to that there's no way (except @dynamicReplacement) AFAIK for a library target to find and call an entry point in a hosting application (by design AFAIU). I don't love @dynamicReplacement, but I do love SAP and would like to be able to use it and not hand roll all that functionality...

Have you tried exploring calling the same methods as Argument Parser does but just from your library, e.g. you could provide a protocol called Benchmark that has a main method that looks like this

  public static func main() async {
    // Setup everything that benchmark needs
    do {
      var command = try parseAsRoot()
      if var asyncCommand = command as? AsyncParsableCommand {
        try await asyncCommand.run()
      } else {
        try command.run()
      }
    } catch {
      exit(withError: error)
    }

  // Record benchmark results etc.
  }

Since all methods are public in Argument Parser you should be able to replicate anything the package is doing in your own main method. Maybe I am missing something here though!

@hassila
Copy link
Contributor Author

hassila commented Mar 16, 2023

I think we have one requirement though which is making the thresholds come through the env vars because we know that different Swift versions have different thresholds due to language improvements and sometimes regressions.

I don't think that really would matter, what would happen in practice is the following:

Benchmark check with Swift 5.5 will build "main" and "PR" and compare them with absolute or relative (most commonly used) thresholds
...
Benchmark check with Swift 5.8 will build "main" and "PR" and compare them with absolute or relative (most commonly used) thresholds

same for different platforms (OS or hardware) - so basically the benchmark checks are gatekeepers for project-specific changes - if the absolute numbers change due to platform or toolchain improvements/regressions, it will be invisible to this approach, as both main and PR will always be built with same toolchains and we focus on the delta between these two builds. If Swift 5.8 is x% faster, that will be true for both the main and PR builds.

Same thing with e.g. malloc regression tolerance - the absolute here is absolute delta between main and PR for the current platform, not absolute absolute really.

Maybe I'm missing something, but ensuring that there are no regressions directly related to the project was our focus (assuming that the OS and compiler folks in general have their performance test suites)?

As you can see on the above details for malloc/syscalls, most of the tests are quite stable across percentiles measured with a few exceptions (which I believe is due to the benchmark under measurement).

I would like to talk about how we could potentially land this. IMO moving the whole thing over at once isn't the best approach. What I think we should do is land them step by step and refactor them on the way to match how your package expects benchmarks to be written. This way we can run them in parallel and also make the PRs more digestible. We also some internal things to figure out.

Ok, let me know what your thoughts are and how the internal discussion resolves, I'll pause this in the meantime.

One issue I ran into now when trying to validate malloc stats, was that the integration tests had deviated a bit visavi the normal benchmarks - and I get a good match on malloc count, but not on actual bytes allocated - but perhaps the jemalloc stats differ in some regard with how your current malloc interposition works - for a trivial test with just mallocs of certain sizes jemalloc gives expected results though, so needs some investigation.

Have you tried exploring calling the same methods as Argument Parser does but just from your library, e.g. you could provide a protocol called Benchmark that has a main method that looks like this

Haven't tried that, maybe that'll work - will try to give it a spin, would be happy to get rid of @dynamicReplacement if possible.

@hassila
Copy link
Contributor Author

hassila commented Mar 17, 2023

I think we have one requirement though which is making the thresholds come through the env vars because we know that different Swift versions have different thresholds due to language improvements and sometimes regressions.

Just realised - that being said - I don't see why you couldn't pull in the thresholds from environment variables, it's just generic swift code there so it can read the environment while setting up thresholds. It's in fact one of the nice things with having programmatic setup of benchmarks declaratively instead of taking the approach of like e.g. xctest with singular test cases being defined as functions - it is easy to have parameter-driven tests if one wants to test many variations and/or extremes (like combination of tasks/thread/connections/etc) and just have a single loop that creates multiple benchmarks driven from e.g. a static array with config info.

But I think the first discussion is what is the fundamentally better way to define thresholds - we've focused on (delta between main and PR) percentile delta percentage deviation and percentile delta absolute deviation that allows gatekeeping PR regressions being merged independent of which toolchain/platform is in use (which we believe is a good way to do it), while NIO had absolute deviation vs. hardcoded threshold which might differ between toolchains/platforms, which while it does the job, just is a bit less robust in our view.

Btw, many, many thanks for the hint on using SAP, it does indeed seem to work - I've just cargo-culted the usage of SAP since years back and never realised it exposed using it like you suggested - will look at eliminating most of the boiler plate and get rid of @dynamicReplacement.

@Lukasa
Copy link
Contributor

Lukasa commented Mar 17, 2023

Maybe I'm missing something, but ensuring that there are no regressions directly related to the project was our focus (assuming that the OS and compiler folks in general have their performance test suites)?

Right, whereas we consider it an asset that we also test our downstream projects. Reporting optimizer misses and other regressions is a useful side-effect of our existing infrastructure.

@hassila
Copy link
Contributor Author

hassila commented Mar 17, 2023

Right I can see that as useful, that is still possible though just slightly different workflow with the CI building just cutting it differently without having to hardcode any reference values:

  1. Build release with toolchain/OS version X, save baseline named reference
  2. Build release with toolchain/OS version Y, save baseline named newAndShiny

Then run swift package benchmark compare baseline reference newAndShiny and/or automated checks like swift package benchmark baseline check reference newAndShiny (if the check fails, report optimizer miss/regression to downstream). Still don't see the need to manually manage threshold there?

(we will do that internally too for deploying new Swift versions for our projects for the same reasons as you)

@Lukasa
Copy link
Contributor

Lukasa commented Mar 17, 2023

It's just a complexity matrix issue, right? We have now escalated to three builds per train, as well as developed a need to keep track of what the previous toolchain version was. Simply writing the results of the last run down saves a lot of complexity.

@hassila
Copy link
Contributor Author

hassila commented Mar 20, 2023

Sure. For the record, for this there’s an option being integrated here:
ordo-one/package-benchmark#116

For the @dynamicReplacement replacement (pun intended) we’ve got this integrated:
ordo-one/package-benchmark#111
Which gives this new minimized boilerplate for benchmarks;
https://github.com/ordo-one/package-benchmark/blob/main/Benchmarks/DateTime/BenchmarkRunner%2BDateTime.swift

@hassila
Copy link
Contributor Author

hassila commented Mar 20, 2023

To clarify possible usage then (I’ll write a small sample later when it’s landed and released), it means you’ll be able to e.g, read thresholds from a json file programmatically in swift and apply that as the absolute thresholds used for checking (no need to wrap it with scripts). You can even write small tweaks adjusting those thresholds (or reading different json files) depending on environment and swift versions of course. So should be no need for extensive scripting or environment variables really.

…e absolute threshold comparisons for schedule_and_run_100k_tasks
@hassila
Copy link
Contributor Author

hassila commented Mar 21, 2023

Updated to Benchmark 1.0.1 which has the new improved boilerplate (thanks @FranzBusch) and added a simple example how absolute threshold checks can be made to address the feedback from @Lukasa - sample output:

hassila@max ~/G/s/Benchmarks (03-15-Benchmark_support)> swift package --disable-sandbox benchmark baseline check --filter schedule_and_run_100k_tasks --check-absolute
Building for debugging...
Build complete! (0.35s)
Building benchmark targets in release mode for benchmark run...
Building WebSocket
Building UDPAndTCP
Building Miscellaneous
Building HTTPRequests
Building HTTPHeaders
Building Futures
Building ByteBuffer
Build complete!

==================
Running Benchmarks
==================

100% [------------------------------------------------------------] ETA: 00:00:00 | Miscellaneous:schedule_and_run_100k_tasks

===========================================================================
Absolute threshold violations for schedule_and_run_100k_tasks:Miscellaneous
===========================================================================
╒══════════════════════════════════════════╤═════════════════╤═════════════════╤═════════════════╕
│ Time (wall clock) (ms, Δ)                │       Threshold │     Current run │   Threshold Abs │
╞══════════════════════════════════════════╪═════════════════╪═════════════════╪═════════════════╡
│ p50                                      │             158 │             159 │               1 │
├──────────────────────────────────────────┼─────────────────┼─────────────────┼─────────────────┤
│ p99                                      │             159 │             167 │               8 │
╘══════════════════════════════════════════╧═════════════════╧═════════════════╧═════════════════╛

New baseline 'Current run' is WORSE than the defined absolute baseline thresholds. (--check-absolute)

error: benchmarkThresholdDeviation
hassila@max ~/G/s/Benchmarks (03-15-Benchmark_support) [1]>

Thresholds here:
https://github.com/ordo-one/swift-nio/blob/b107d947762081213efed1916aa9fdf9269af3ce/Benchmarks/Benchmarks/Miscellaneous/Miscellaneous.swift#L26
and used here:
https://github.com/ordo-one/swift-nio/blob/b107d947762081213efed1916aa9fdf9269af3ce/Benchmarks/Benchmarks/Miscellaneous/Miscellaneous.swift#L164

@hassila
Copy link
Contributor Author

hassila commented Oct 6, 2023

Closing this as there's #2534

@hassila hassila closed this Oct 6, 2023
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants