|
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)) { |
|
actors[msg.Recipient].HandleMessage(msg.Body); |
|
} |
|
|
|
Console.WriteLine(watch.Elapsed); |
|
} |
|
} |
|
|
|
public class Actor {using System; |
|
using System.Collections.Concurrent; |
|
using System.Collections.Generic; |
|
using System.Diagnostics; |
|
|
|
namespace SimRing |
|
{ |
|
class Program |
|
{ |
|
static void Main(string[] args) |
|
{ |
|
// warm up (Jit) |
|
Execute(); |
|
|
|
// run |
|
var elpased = Execute(); |
|
Console.WriteLine(elpased); |
|
} |
|
|
|
static TimeSpan Execute() |
|
{ |
|
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)) |
|
{ |
|
actors[msg.Recipient].HandleMessage(msg.Body); |
|
} |
|
watch.Stop(); |
|
|
|
return watch.Elapsed; |
|
} |
|
} |
|
|
|
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) |
|
{ |
|
_counter++; |
|
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 ConcurrentQueue<Message> _messages = new ConcurrentQueue<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); |
|
} |
|
} |
|
} |
|
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) { |
|
_counter++; |
|
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); |
|
} |
|
} |
|
} |