{"id":16210310,"url":"https://github.com/johannesdeml/networkbenchmarkdotnet","last_synced_at":"2025-03-16T11:30:47.372Z","repository":{"id":56505845,"uuid":"297728522","full_name":"JohannesDeml/NetworkBenchmarkDotNet","owner":"JohannesDeml","description":"Low-level dotnet network benchmark for UDP socket performance (.NET and Unity compatible)","archived":false,"fork":false,"pushed_at":"2023-04-06T21:21:36.000Z","size":604,"stargazers_count":87,"open_issues_count":1,"forks_count":11,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-02-27T08:19:00.558Z","etag":null,"topics":["benchmark","client","csharp","dotnet","enet","hacktoberfest","net-core","net50","netcoreserver","network","network-benchmark","server","sockets","udp","udp-socket-performance","unity"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JohannesDeml.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-09-22T17:52:55.000Z","updated_at":"2025-01-23T17:00:52.000Z","dependencies_parsed_at":"2024-01-13T23:17:38.725Z","dependency_job_id":"c24b1dc2-eb08-4e66-abba-fdc61f89d716","html_url":"https://github.com/JohannesDeml/NetworkBenchmarkDotNet","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohannesDeml%2FNetworkBenchmarkDotNet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohannesDeml%2FNetworkBenchmarkDotNet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohannesDeml%2FNetworkBenchmarkDotNet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohannesDeml%2FNetworkBenchmarkDotNet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JohannesDeml","download_url":"https://codeload.github.com/JohannesDeml/NetworkBenchmarkDotNet/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243814864,"owners_count":20352037,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["benchmark","client","csharp","dotnet","enet","hacktoberfest","net-core","net50","netcoreserver","network","network-benchmark","server","sockets","udp","udp-socket-performance","unity"],"created_at":"2024-10-10T10:36:58.587Z","updated_at":"2025-03-16T11:30:46.996Z","avatar_url":"https://github.com/JohannesDeml.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Network Benchmark .NET\n\n*Low Level .NET 6 Networking libraries benchmarked for UDP socket performance*\n\n![Screenshot](./Docs/screenshot.png)\n\n[![Releases](https://img.shields.io/github/release/JohannesDeml/NetworkBenchmarkDotNet/all.svg)](../../releases) [![.NET 6.0](https://img.shields.io/badge/.NET-6.0-blueviolet.svg)](https://dotnet.microsoft.com/download/dotnet/6.0)\n\n## Table of Contents\n\n1. [Description](#description)\n2. [Benchmark Setup](#benchmark-setup)\n3. [Benchmark Results](#benchmark-results)\n4. [Installation](#installation)\n5. [Usage](#usage)\n6. [Contributions](#contributions)\n\n\n\n## Description\n\nNBN is a benchmark for low level networking libraries using UDP and can be used with [Unity](https://unity3d.com) and for [.Net Core](https://en.wikipedia.org/wiki/.NET_Core) standalone server applications. The benchmark focuses on latency, performance and scalability.\n\n### Supported Libraries\n\n* [ENet-CSharp](https://github.com/nxrighthere/ENet-CSharp) (v 2.4.8)\n  * Wrapper for [ENet](https://github.com/lsalzman/enet), building a reliable sequenced protocol on top of UDP\n  * Max concurrent connections are limited to 4095 due to the protocol\n  * Packetsize overhead: 10 bytes\n  * [Unity Client Example](https://github.com/JohannesDeml/ENetUnityMobile)\n* [LiteNetLib](https://github.com/RevenantX/LiteNetLib) (v 1.0.1)\n  * Very feature-rich library\n  * Packetsize overhead: 1 byte for unreliable, 4 bytes for reliable\n  * [Unity Client Example](https://github.com/RevenantX/NetGameExample)\n* [Kcp2k](https://github.com/vis2k/kcp2k) (v 1.34.0)\n  * Port of KCP with 100% C# Code, Future Technology for [Mirror-NG](https://github.com/MirrorNG/MirrorNG)\n  * Packetsize overhead: 24 byte\n  * [Unity Example](https://github.com/vis2k/kcp2k)\n* [NetCoreServer](https://github.com/chronoxor/NetCoreServer) (v 6.7.0)\n  * Pure C# / .Net library for TCP/UDP/SSL with no additional protocols on top\n  * Packetsize overhead: 0 bytes, but you have to invent the wheel yourself\n  * [Unity Client Example](https://github.com/JohannesDeml/Unity-Net-Core-Networking-Sockets)\n\n\n## Benchmark Setup\n\n### Hardware\n\n* Ubuntu VPS\n  * Virtual private server with dedicated CPU's running - [Hardware](https://www.netcup.eu/bestellen/produkt.php?produkt=2624)\n  * Ubuntu 22.04.2 LTS x86-64 Kernel 5.15.0-48-generic\n    ```\n    $\u003e hostnamectl\n             Chassis: vm\n      Virtualization: kvm\n    Operating System: Ubuntu 22.04.2 LTS\n              Kernel: Linux 5.15.0-48-generic\n        Architecture: x86-64\n     Hardware Vendor: netcup\n      Hardware Model: KVM Server\n    ```\n  \n    \n  \n* Ubuntu Desktop / Windows Desktop\n  * Desktop PC from 2020 - [Hardware](https://pcpartpicker.com/user/JohannesDeml/saved/zz7yK8)\n  * Windows 11 Pro x86-64 Build 22621,1485 (22H2)\n  * Ubuntu 22.04.2 LTS x86-64 Kernel 5.19.0-38-generic\n\n### Software\n\n* [.NET](https://dotnet.microsoft.com/download/dotnet) 6.0.13 on Ubuntu, 6.0.15 on Windows\n* [BenchmarkDotNet](https://github.com/dotnet/BenchmarkDotNet) 0.13.5\n\n### Procedure\nFor the two desktop setups, the benchmarks are run on a restarted system with 5 minutes idle time before starting the benchmark. They are run with admin privileges and all unnecessary other processes are killed before running the benchmarks. For Ubuntu VPS, the benchmarks are run through continuous integration on a typical indie server setup with other processes running as well. After the benchmarks are run, a list of all running processes to make them more reproducible. To reproduce the benchmarks, run `sudo sh linux-benchmark.sh` or `win-benchmark.bat` . If you want to execute directly from the compiled program, run `./NetworkBenchmarkDotNet -b Essential`.\n\n## Benchmark Results\nThe raw data and additional files can be downloaded from the [release section](../../releases).\n\n### Benchmark [PingPongUnreliable](./NetworkBenchmarkDotNet/PredefinedBenchmarks/UnreliablePerformanceBenchmark.cs)\n\nRuns the benchmark with **500** clients, which pingpong **1 message** each with the server with **unreliable** transmission. The benchmark runs until a total of **500,000** messages are sent to the server and back to the clients. Message size is **32 bytes**.  \nThis test is for getting an idea of an average roundtrip time (lower is better).\n![PingPong Unreliable .NET Benchmark chart](./Docs/nbn-pingpongunreliable-1.1.0.png)\n\n### Benchmark [PingPongReliable](./NetworkBenchmarkDotNet/PredefinedBenchmarks/ReliablePerformanceBenchmark.cs)\n\nRuns the benchmark with **500** clients, which pingpong **1 message** each with the server with **reliable** transmission. The benchmark runs until a total of **500,000** messages are sent to the server and back to the clients. Message size is **32 bytes**.  \nThis test is for getting an idea of an average roundtrip time (lower is better).\n![PingPong Reliable .NET Benchmark chart](./Docs/nbn-pingpongreliable-1.1.0.png)\n\n### Benchmark [PingPongBatchedUnreliable](./NetworkBenchmarkDotNet/PredefinedBenchmarks/UnreliablePerformanceBenchmark.cs)\n\nRuns the benchmark with **500** clients, which pingpong **10 messages** each with the server with **unreliable** transmission. The benchmark runs until a total of **500,000** messages are sent to the server and back to the clients. Message size is **32 bytes**.  \nThis test is for multiplexing / message merging performance (higher is better).\n![PingPong Batched Unreliable .NET Benchmark chart](./Docs/nbn-pingpongbatchedunreliable-1.1.0.png)\n\n### Benchmark [SampleEchoSimple](./NetworkBenchmarkDotNet/PredefinedBenchmarks/SamplingBenchmark.cs)\n\nRuns the benchmark with **1** client, which pingpong **10 messages** each with the server. The benchmark runs until a total of **100,000** messages are sent to the server and back to the clients. Message size is **128 bytes**.  \nThis test collects information about generated garbage and CPU times while running the benchmark. Those results can be analyzed with [PerfView](https://github.com/microsoft/perfview) on Windows.\n\n### Overview\nThis is a comparison between all tests with their message throughput (higher is better).\n\n![Network Benchmark .NET results overview](./Docs/nbn-overview-1.1.0.png)\n\n### Notes\n\n* Ubuntu outperforms windows in almost all tests and libraries. \n* The benchmarks are run locally and therefor a lot of processing power is used for simulating the clients. Therefore, this benchmark does not include a CCU comparison, but is sufficient to compare different libraries for the same setup.\n* Also the network latency results do not show any costs of the network itself, but only the cost of the application layer in the round trip time. Since multiple clients are run at the same time, this time with be smaller than presented here.\n* Creation, Connection and Disconnection and Disposal of the Server and Clients is not included in the performance benchmarks, but is included in the .nettrace files from the Sampling benchmark.\n* To access the Sampling results, you can use [PerfView](https://github.com/microsoft/perfview) to open the `.nettrace` files.\n* Kcp2k has been recently added and might have some room for improvements. Especially using `Thread.Sleep` on Windows creates [noticeable delays](https://social.msdn.microsoft.com/Forums/vstudio/en-US/facc2b57-9a27-4049-bb32-ef093fbf4c29/threadsleep1-sleeps-for-156-ms?forum=clr). For now it is excluded of the predefined benchmarks, until its execution and cleanup are improved.\n* This is not a general purpose benchmark for every and any game type. Different games have different requirements. I hope these benchmarks help you as a smoke test and give you the possibility to quickly test how your hardware handles the different libraries.\n\n\n## Installation\n\nMake sure you have [.Net 6 SDK](https://dotnet.microsoft.com/download) installed.\n\nThen just open the solution file with Visual Studio/Rider/Visual Studio Code and build it. Note that results of the benchmarks can be very different with a different operating system and hardware.\n\n## Usage\nIn general there are two different types of benchmarks: Custom and predefined benchmarks. Custom benchmarks and be defined through the [command-line options](#command-line-options). Predefined Benchmarks are set in code and are executed through [BenchmarkDotNet](https://github.com/dotnet/BenchmarkDotNet). They are used for the statistics presented here and are more accurate and better reproducible then Custom benchmarks. However, they also take a longer time to finish. You can also run the clients and server on different machines to test the libraries over your local network or remotely (see [remote benchmarks](#remote-benchmarks)).\n\n### Custom Benchmarks\n\nYou can run custom benchmarks through the command-line. Use can test multiple settings and its combinations in an easy and quick way. The tests will just run once and are not as accurate as running a predefined benchmark. An example for running a benchmark might be `./NetworkBenchmarkDotNet --library ENet --transmission Unreliable --clients 100 --duration 10 `\n\n#### Command-line Options (`./NetworkBenchmarkDotNet --help`)\n```\nUsage:\n  NetworkBenchmarkDotNet [options]\n\nOptions:\n  -b, --benchmark                          Run predefined benchmarks [default:\n  \u003cAll|Custom|Essential|Performance|Qui    Custom]\n  ck|Sampling\u003e\n  -m, --execution-mode                     Control what parts to run [default:\n  \u003cClient|Complete|Server\u003e                 Complete]\n  -t, --test \u003cManual|PingPong\u003e             Test type [default: PingPong]\n  --transmission \u003cReliable|Unreliable\u003e     Transmission type [default:\n                                           Unreliable]\n  -l, --library                            Library target [default: ENet]\n  \u003cENet|Kcp2k|LiteNetLib|NetCoreServer\u003e\n  -d, --duration \u003cduration\u003e                Test duration in seconds (-1 for\n                                           manual stopping) [default: 10]\n  --address \u003caddress\u003e                      IP Address, can be ipv4 (e.g.\n                                           127.0.0.1) or ipv6 (e.g. ::1)\n                                           [default: ::1]\n  --port \u003cport\u003e                            Socket Port [default: 3330]\n  --clients \u003cclients\u003e                      # Simultaneous clients [default: 500]\n  --parallel-messages                      #Parallel messages per client\n  \u003cparallel-messages\u003e                      [default: 1]\n  --message-byte-size                      Message byte size sent by clients\n  \u003cmessage-byte-size\u003e                      [default: 32]\n  --message-payload \u003cOnes|Random|Zeros\u003e    Message load sent by clients\n                                           [default: Random]\n  --verbose                                Verbose output of test steps and\n                                           errors [default: True]\n  --client-tick-rate \u003cclient-tick-rate\u003e    Client ticks per second if supported\n                                           [default: 60]\n  --server-tick-rate \u003cserver-tick-rate\u003e    Server ticks per second if supported\n                                           [default: 60]\n  --use-native-sockets                     Use native Sockets (LiteNetLib only)\n                                           [default: True]\n  --version                                Show version information\n  -?, -h, --help                           Show help and usage information\n```\n\n### Predefined Benchmarks\n\nPredefined benchmarks take some time to run, but generate reproducible numbers. The easiest way to run a predefined benchmark is to run `win-benchmark.bat` on windows or `sh linux-benchmark.sh` on windows.\n\n#### Types\n\n* **Quick** (\u003c1min): Runs a quick benchmark with whatever is set in [QuickBenchmark.cs](../../blob/master/NetworkBenchmarkDotNet/PredefinedBenchmarks/QuickBenchmark.cs)\n* **Performance** (\u003e15min): High Performance statistical test with all included libraries\n* **Sampling** (\u003c1min): Test with all included libraries using cpu sampling and memory allocation statistics\n* **Essential** (\u003e15min): Running Performance + Garbage Benchmark\n\n![Run Predefined Benchmark windows command-line screenshot](./Docs/run-predefined-benchmark.png)\n\n### Remote Benchmarks\n\nTo test a library remotely, you can use the parameter `--execution-mode Server` and `--execution-mode Client` respectively. This setup requires to first start the server with the correct library (and probably an indefinite execution duration) on your target server, and then the client process. Here is an example:  \nServer: `./NetworkBenchmarkDotNet --library ENet --transmission Reliable --execution-mode Server --address YOUR_ADDRESS -d -1`  \nClient: `./NetworkBenchmarkDotNet --library ENet --transmission Reliable --execution-mode Client --address YOUR_ADDRESS --clients 100 -d 10`\n\nIf you change the address in `QuickBenchmark.cs`, you can also run a more sophisticated remote benchmark this way.\n\n## Contributions\n\nYour favorite library is missing, or you feel like the benchmarks are not testing everything relevant? Let's evolve the benchmark together! Either hit me up via [E-mail](mailto:public@deml.io) to discuss your idea, or [open an issue](../../issues), or make a pull request directly. There are a few rules in order to not make the benchmark too cluttered.\n\n### Adding a Library\n\nYour new proposed library ... \n\n* works with Unity as a Client\n* works with .NET 6 for the server \n* uses UDP (additional RUDP would be nice)\n* is Open Source (can still be commercial)\n* is stable enough not to break in the benchmarks\n* is in active development\n* adds value to the benchmarks\n\n#### How to add a library\n\n1. Add a new folder inside the NetworkBenchmarkDotNet solution with the name of your library\n2. Add a script called `YourLibraryBenchmark.cs` which implements [ANetworkBenchmark](../../blob/master/NetworkBenchmarkDotNet/Libraries/ANetworkBenchmark.cs)\n3. Add your library name to the [NetworkLibrary](../../blob/master/NetworkBenchmarkDotNet/Libraries/NetworkLibrary.cs) enum\n4. Add your Implementation Constructor to `INetworkBenchmark.CreateNetworkBenchmark()`\n5. Use the `-l ` argument (or `BenchmarkSetup.Library`) to test your library and if everything works as expected.\n6. Change `[Params(NetworkLibrary.Kcp2k)]` in `QuickBenchmark.cs` to your library and run `./NetworkBenchmarkDotNet -b Quick` to see, if your library works with high CCU and looping benchmarks with BenchmarkDotNet\n8. Create a PR including your benchmark results 🎉\n\n\n\n## License\n\n[MIT](./LICENSE)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohannesdeml%2Fnetworkbenchmarkdotnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohannesdeml%2Fnetworkbenchmarkdotnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohannesdeml%2Fnetworkbenchmarkdotnet/lists"}