Skip to content

Instantly share code, notes, and snippets.



Last active Jul 10, 2020
What would you like to do?
Naive ring benchmark in .NET Core using simulated actors

This is a naive (see for yourself!) implementation that explores the idea of simulating a ring of N actors that send the messages to each over M times.

Concept of the ring benchmark and simulated actors is taken from the gist by Preetam Jinka:

Given N=1000 and M=1000, the result on my machine is:

/usr/local/share/dotnet/dotnet /Users/rinat/proj/core/SimRing/bin/Release/netcoreapp2.0/SimRing.dll

This naive implementation is a start for building up a deterministic simulation of a cluster in a world full of failures. Another building block is the time simulation:


  • How would you implement a ring benchmark in golang?
  • This .NET Core implementation is way faster than Erlang. What does Erlang spend time on?
  • Why is this implementation faster than FoundationDB Flow? What extra work could the Flow do?

I want to learn more! What is next?

Next, we'll plug into .NET Core async/await to simulate processes running in parallel. Check it out.

MIT License 2018 Rinat Abdullin
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace SimRing {
class Program {
static void Main(string[] args) {
const int n = 1000;
const int m = 1000;
var actors = new List<Actor>();
var sim = new Sim();
for (int i = 0; i < n; i++) {
var next = (i + 1) % n;
actors.Add(new Actor(next, sim, m));
sim.Send(0, new {hello = "world"});
var watch = Stopwatch.StartNew();
while (sim.GetNextMessage(out var msg)) {
public class Actor {
readonly int NextActor;
int _counter;
readonly Sim _sim;
readonly int _m;
public Actor(int nextActor, Sim sim, int m) {
NextActor = nextActor;
_sim = sim;
_m = m;
public void HandleMessage(object message) {
if (_counter <= _m) {
_sim.Send(NextActor, message);
public struct Message {
public readonly int Recipient;
public readonly object Body;
public Message(int recipient, object body) {
Recipient = recipient;
Body = body;
public sealed class Sim {
readonly Queue<Message> _messages = new Queue<Message>();
public void Send(int recipient, object message) {
_messages.Enqueue(new Message(recipient, message));
public bool GetNextMessage(out Message msg) {
return _messages.TryDequeue(out msg);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment