1
0
Fork 0
mirror of https://github.com/pry/pry.git synced 2022-11-09 12:35:05 -05:00
Commit graph

6 commits

Author SHA1 Message Date
Kyrylo Silin
0c677b7a1d ring: change guard priority so that the value at index can be read
Fixes #2199 (`_out_` Ring is ill-addressible)
2021-06-28 22:33:20 +03:00
Kyrylo Silin
18c45d26c5 rubocop: enable the Style/FrozenStringLiteralComment cop
This will greatly ease Pry support on Ruby 3.0 (when it's out).
2019-05-08 00:13:17 +03:00
Kyrylo Silin
e5914564a8 spec/helper.rb -> spec/spec_helper.rb
`helper.rb` is a legacy name from Bacon days. Since we use RSpec, the convention
is to use `spec/spec_helper.rb`. Applying the principle of least astonishment
here.
2019-03-07 23:21:11 +02:00
zaru@sakuraba
bb73fd1f19 ring: fix swap parts of array in to_a and index access 2018-11-26 08:46:09 +09:00
Kyrylo Silin
a4e9dd2e7d ring: rewrite the class to improve API
Currently, the Ring class is written with help of Hash as backend store.
According to the comments, the implementation should behave like a circular
buffer, however it doesn't. Upon reaching maximum capacity Ring doesn't replace
old elements but keeps writing to new cells, deleting old cells, so that the
hash contains `nil` entries.

The new implementation is based on Array and seems to be closer to the actual
Ring. Older elemens get overwritten with newer ones.

This class also includes Enumerable, however none of our APIs take advantage of
it, so it seems like an overkill. There was also a problem with with this API
because of the above-mentioned nils. For example, if the ring exceeds its
maximum size, then callin `Enumerable#first` on it returns `nil`.

The new implementation deals with this with removal of Enumerable. The `#[]`
syntax is preserved, and now `ring[0]` returns an actual element instead of
`nil`. In case users need the Enumerable functionality, they can call
`Ring#to_a` to build the array, which supports the wanted methods.

As for the speed, the new implementation is:

* slower overall because it's thread-safe
* faster without mutexes for `#<<`
* slower without mutexes for `#[]`

Benchmark for old implementation:

```
Warming up --------------------------------------
             Ring#<<   223.451k i/100ms
             Ring#[]     2.837k i/100ms
Calculating -------------------------------------
             Ring#<<    223.157B (± 3.4%) i/s -    778.097B
             Ring#[]     82.485M (± 9.4%) i/s -    402.602M in   4.957792s
```

Benchmark for this implementation:

```
Warming up --------------------------------------
             Ring#<<   211.587k i/100ms
             Ring#[]     1.974k i/100ms
Calculating -------------------------------------
             Ring#<<    211.385B (± 2.8%) i/s -    698.439B
             Ring#[]     40.292M (±17.0%) i/s -    190.069M in   4.971195s
```

The benchmark:

```rb
require './lib/pry'
require 'benchmark/ips'

Benchmark.ips do |x|
  empty_ring = Pry::Ring.new(100)
  populated_ring = Pry::Ring.new(100)
  150.times { |i| populated_ring << i }

  x.report("Ring#<<") do |times|
    empty_ring << times
  end

  x.report("Ring#[]") do |times|
    populated_ring[0]
    populated_ring[1]
    populated_ring[2]

    populated_ring[-1]
    populated_ring[-2]
    populated_ring[-3]

    populated_ring[1..2]
    populated_ring[-2..-1]
    populated_ring[-2..3]

    populated_ring[0..-1]

    populated_ring[2..-1]
    populated_ring[-1..10]

    populated_ring[-1..0]
    populated_ring[-1..1]
  end
end
```
2018-10-21 05:31:45 +08:00
Kyrylo Silin
2519818cc9 Rename HistoryArray to Ring
`HistoryArray` is a very specific name and it doesn't tell the reader what
it *really* means unless you read its code or the docs of the class.

On the other hand, `Ring` is a [very well-known term][1], which means exactly
what `HistoryArray` does. The alias name for it is circular buffer. I chose
`Ring` because it is shorter and used by Golang, so I expect programmers to
be familiar with `Ring`.

[1]: https://en.wikipedia.org/wiki/Circular_buffer
2018-10-20 00:36:22 +08:00
Renamed from spec/history_array_spec.rb (Browse further)