Use circular buffer instead of std::queue
krawq opened this issue · comments
An idea to greatly improve performance would be a CircularQueue type.
Performance of circular buffer is an order of magnitude faster that the deque container used by STL (underlying container of std::queue) as per the following benchmark (consider case with vector with reserve() as the vector is pre-allocated):
Benchmark
One example is the use in the spdlog lib : spdlog
Its using a fixed size std::vector and add the interface for circular buffer around it.
After using the circular_q of spdlog and changing a bit PolyM to benchmark I get similar in 1-to-1 and 2-to-1 test (with 10 millions msg counts).
I think results are a bit worse with low reserved number as with a high number of msg we fill the maximum number of values very quickly and encounter the push lock (as queue is full). If we adjust the maximum size to reserve we get slight improvement (not counting the first time to allocate the queue obviously).
Message count = 10'000'000
Test 1-to-1 message order... Duration : 1922ms OK!
Test 2-to-1 message order... Duration : 4293ms OK!
[CIRCULAR - Reserved 4096 msg] Test 1-to-1 message order... Duration : 2272ms OK!
[CIRCULAR - Reserved 4096 msg] Test 2-to-1 message order... Duration : 4834ms OK!
[CIRCULAR - Reserved 10000000 msg] Test 1-to-1 message order... Duration : 1617ms OK!
[CIRCULAR - Reserved 10000000 msg] Test 2-to-1 message order... Duration : 4054ms OK!
Performances are in the range of +10% / +20% depending on msg counts etc...
In real world scenario, performance gain is likely to fade as its unlikely to run that high numbers of msg.
Conclusion is that mutex performance is the limiting factor here, the queue is blazing fast !