apple / swift-nio

Event-driven network application framework for high performance protocol servers & clients, non-blocking.
https://swiftpackageindex.com/apple/swift-nio/documentation
Apache License 2.0
7.85k stars 633 forks source link

Add TaskExecutor conformance to EventLoops #2732

Open fabianfett opened 1 month ago

fabianfett commented 1 month ago

Add TaskExecutor conformance to EventLoops

Motivation

Swift 6 introduces the option to supply your own task executors to the Swift concurrency runtime (SE-0417). SwiftNIO's EventLoop should conform to the new TaskExecutor protocol to support running Swift concurrency Tasks on it. This will allow fewer context switches in Swift on server applications.

Modifications

Result

Adopters can use ELs as task executors

FranzBusch commented 1 month ago

Can we also add another benchmark for the NIOAsyncChannel that uses the task executor next to the global executor hook to prove that this indeed does what we want it to do.

fabianfett commented 1 month ago

Performance results on my machine:

==================
NIOPosixBenchmarks
==================

TCPEcho pure NIO 1M times
╒═════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                  │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞═════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Context switches        │    4370 │    4370 │    4370 │    4370 │    4370 │    4370 │    4370 │       1 │
├─────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Malloc (total) *        │     428 │     428 │     428 │     428 │     428 │     428 │     428 │       1 │
├─────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (ms) * │    4537 │    4537 │    4537 │    4537 │    4537 │    4537 │    4537 │       1 │
╘═════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛

TCPEchoAsyncChannel pure async/await 1M times
╒═════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                  │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞═════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Context switches (K)    │     148 │     148 │     148 │     148 │     148 │     148 │     148 │       1 │
├─────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Malloc (total) (K) *    │    1492 │    1492 │    1492 │    1492 │    1492 │    1492 │    1492 │       1 │
├─────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (ms) * │    8431 │    8431 │    8431 │    8431 │    8431 │    8431 │    8431 │       1 │
╘═════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛

TCPEchoAsyncChannel using globalHook 1M times
╒═════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                  │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞═════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Context switches        │    9498 │    9498 │    9498 │    9498 │    9498 │    9498 │    9498 │       1 │
├─────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Malloc (total) (K) *    │     221 │     221 │     221 │     221 │     221 │     221 │     221 │       1 │
├─────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (ms) * │    9011 │    9011 │    9011 │    9011 │    9011 │    9011 │    9011 │       1 │
╘═════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛

TCPEchoAsyncChannel using task executor preference 1M times
╒═════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                  │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞═════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Context switches        │    8352 │    8352 │    8352 │    8352 │    8352 │    8352 │    8352 │       1 │
├─────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Malloc (total) (K) *    │    6175 │    6175 │    6175 │    6175 │    6175 │    6175 │    6175 │       1 │
├─────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (ms) * │    9336 │    9336 │    9336 │    9336 │    9336 │    9336 │    9336 │       1 │
╘═════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛