<commit_before>Notes
=====

Disruptor Overview
----------------------------

This is a port of the [LMAX Disruptor](https://github.com/LMAX-Exchange/disruptor) into the Go programming language. It retains the essence and spirit of the Disruptor and utilizes a lot of the same abstractions and concepts, but does not maintain the same API.

On my MacBook Pro (Intel Core i7 3740QM @ 2.7 Ghz) using Go 1.2.1, I was able to push over **700 million messages per second** (yes, you read that right) from one goroutine to another goroutine. The message being transferred between the two CPU cores was simply the incrementing sequence number, but literally could be anything. Note that your mileage may vary and that different operating systems can introduce significant “jitter” into the application by taking control of the CPU. Linux and Windows have the ability to assign a given process to specific CPU cores which reduces jitter significantly.  Parenthetically, when the Disruptor code is compiled and run on a Nexus 5, it can push about 15-20 million messages per second.

Once initialized and running, one of the preeminent design considerations of the Disruptor is to produce no garbage thus avoiding the need for GC altogether and to avoid locks at all costs. The current channel implementation maintains a big, fat lock around enqueue/dequeue operations and maxes out on the aforementioned hardware at about 25M messages per second for uncontended access-—more than an order of magnitude slower when compared to the Disruptor.  The same channel, when contended between OS threads (`GOMAXPROCS=2` or more) only pushes about 7 million messages per second.

Benchmarks
----------------------------
Each of the following benchmark tests sends an incrementing sequence message from one goroutine to another. The receiving goroutine asserts that the message is received is the expected incrementing sequence value. Any failures cause a panic. All tests were run using `GOMAXPROCS=2`.

Scenario | Per Operation Time
-------- | ------------------
Channels: Buffered, Blocking, GOMAXPROCS=1 | 58.6 ns/op
Channels: Buffered, Blocking, GOMAXPROCS=2 | 86.6 ns/op
Channels: Buffered, Blocking, GOMAXPROCS=3, Contended Write | 194 ns/op
Channels: Buffered, Non-blocking, GOMAXPROCS=1| 73.9 ns/op
Channels: Buffered, Non-blocking, GOMAXPROCS=2| 72.3 ns/op
Channels: Buffered, Non-blocking, GOMAXPROCS=3, Contended Write | 259 ns/op
Disruptor: Writer, Reserve One | 4.3 ns/op
Disruptor: Writer, Reserve Many | 1.1 ns/op
Disruptor: Writer, Await One | 3.5 ns/op
Disruptor: Writer, Await Many | 1.0 ns/op
Disruptor: SharedWriter, Reserve One | 15.4 ns/op
Disruptor: SharedWriter, Reserve Many | 2.5 ns/op
Disruptor: SharedWriter, Reserve One, Contended Write | nn.n ns/op<commit_msg>Updated readme.<commit_after>Notes
=====

Disruptor Overview
----------------------------

This is a port of the [LMAX Disruptor](https://github.com/LMAX-Exchange/disruptor) into the Go programming language. It retains the essence and spirit of the Disruptor and utilizes a lot of the same abstractions and concepts, but does not maintain the same API.

On my MacBook Pro (Intel Core i7 3740QM @ 2.7 Ghz) using Go 1.2.1, I was able to push over **700 million messages per second** (yes, you read that right) from one goroutine to another goroutine. The message being transferred between the two CPU cores was simply the incrementing sequence number, but literally could be anything. Note that your mileage may vary and that different operating systems can introduce significant “jitter” into the application by taking control of the CPU. Linux and Windows have the ability to assign a given process to specific CPU cores which reduces jitter significantly.  Parenthetically, when the Disruptor code is compiled and run on a Nexus 5, it can push about 15-20 million messages per second.

Once initialized and running, one of the preeminent design considerations of the Disruptor is to produce no garbage thus avoiding the need for GC altogether and to avoid locks at all costs. The current channel implementation maintains a big, fat lock around enqueue/dequeue operations and maxes out on the aforementioned hardware at about 25M messages per second for uncontended access-—more than an order of magnitude slower when compared to the Disruptor.  The same channel, when contended between OS threads (`GOMAXPROCS=2` or more) only pushes about 7 million messages per second.

Benchmarks
----------------------------
Each of the following benchmark tests sends an incrementing sequence message from one goroutine to another. The receiving goroutine asserts that the message is received is the expected incrementing sequence value. Any failures cause a panic. All tests were run using `GOMAXPROCS=2`.

Scenario | Per Operation Time
-------- | ------------------
Channels: Buffered, Blocking, GOMAXPROCS=1 | 58.6 ns/op
Channels: Buffered, Blocking, GOMAXPROCS=2 | 86.6 ns/op
Channels: Buffered, Blocking, GOMAXPROCS=3, Contended Write | 194 ns/op
Channels: Buffered, Non-blocking, GOMAXPROCS=1| 73.9 ns/op
Channels: Buffered, Non-blocking, GOMAXPROCS=2| 72.3 ns/op
Channels: Buffered, Non-blocking, GOMAXPROCS=3, Contended Write | 259 ns/op
Disruptor: Writer, Reserve One | 4.3 ns/op
Disruptor: Writer, Reserve Many | 1.1 ns/op
Disruptor: Writer, Await One | 3.5 ns/op
Disruptor: Writer, Await Many | 1.0 ns/op
Disruptor: SharedWriter, Reserve One | 14.5 ns/op
Disruptor: SharedWriter, Reserve Many | 2.5 ns/op
Disruptor: SharedWriter, Reserve One, Contended Write | nn.n ns/op
{'fraction_non_alphanumeric': 0.08429602888086643, 'fraction_numerical': 0.021660649819494584, 'mean_word_length': 4.078826764436297, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3562116', 'n_tokens_mistral': 1573, 'n_tokens_neox': 1466, 'n_words': 766}