I was just reading about ring buffer the other day and I was fascinated by how simple yet efficient it is.
I've implemented a ring (circular) buffer in Ruby and I'm just wondering if there's anything I can improve, and also how to properly measure its performance.
Ring buffer:
class RingBuffer
attr_accessor :ring, :size, :start, :end
def initialize(size)
@ring = Array.new(size)
@size = size
@start, @end = 0, 0
end
def full?
(@end + 1) % @size == @start
end
def empty?
@end == @start
end
def write(element)
return if full?
@ring[@end] = element
@end = (@end + 1) % @size
end
def read
return if empty?
element = @ring[@start]
@start = (@start + 1) % @size
element
end
def clear
@ring = Array.new(@size)
@start, @end = 0, 0
end
end
Speed test:
require_relative 'ring_buffer.rb'
buffer_size = 1024*1024
rb = RingBuffer.new(buffer_size)
t0 = Time.now
(buffer_size-1).times {|idx|
rb.write idx
}
t1 = Time.now
(buffer_size-1).times {|idx|
rb.read
}
t2 = Time.now
t_all = (t2-t0) * 1000.0
t_avg_w = (t1 - t0) * 1000.0 * 1000.0 / buffer_size
t_avg_r = (t2 - t1) * 1000.0 * 1000.0 / buffer_size
printf("All: %.02fms\n", t_all)
printf("Avg. write: %.02fμs\n", t_avg_w)
printf("Avg. read: %.02fμs\n", t_avg_r)