README.rdoc in bychar-1.2.1 vs README.rdoc in bychar-2.0.0
- old
+ new
@@ -4,11 +4,48 @@
* Only forward
* By a single character
* Without skipping
+This is how most of recursive-descent parsers and stateful parsers would work. However,
+reading a simple IO object byte by byte in Ruby is very slow. Orders slower in fact.
+Therefore, this gem creates a simple wrapper that you can get like this:
+
+ wrapper = Bychar.wrap(io)
+ loop do
+ c = wrapper.read_one_char!
+ rescye Bychar::EOF
+ # Your IO ran out
+ end
+
The wrapper will cache some bytes from the passed IO object which will make parsing
-faster when you advance your parser char by char.
+faster when you advance your parser char by char. You should not do any checks on the returned char
+since the reader will raise a Bychar::EOF once the IO is depleted. That exception inherits from EOFError.
+
+== Performance
+
+I told you reading char by char is not the best strategy. On Ruby 1.9:
+
+ Bare IO using read(1): 3.400000 1.900000 5.300000 ( 5.300798)
+ Bychar using StringIO: 1.790000 0.010000 1.800000 ( 1.795277)
+ Bychar using a String buffer: 1.760000 0.000000 1.760000 ( 1.760440)
+ Platform-picked Bychar.wrap(io) Bychar::ReaderStrbuf: 1.770000 0.010000 1.780000 ( 1.776339)
+
+while on Ruby 1.8 it is kinda sad:
+
+ Bare IO using read(1): 2.380000 0.000000 2.380000 ( 2.393260)
+ Bychar using StringIO: 2.270000 0.010000 2.280000 ( 2.275631)
+ Bychar using a String buffer: 2.920000 0.000000 2.920000 ( 2.924574)
+ Platform-picked Bychar.wrap(io) Bychar::ReaderBare: 2.380000 0.010000 2.390000 ( 2.384414)
+
+And on JRuby it's different still:
+
+ Bare IO using read(1): 1.610000 0.040000 1.650000 ( 1.180000)
+ Bychar using StringIO: 0.730000 0.020000 0.750000 ( 0.603000)
+ Bychar using a String buffer: 1.040000 0.040000 1.080000 ( 0.790000)
+ Platform-picked Bychar.wrap(io) Bychar::ReaderIOBuf: 0.560000 0.030000 0.590000 ( 0.546000)
+
+As you can see, Bychar will do some work to pick an implementation that makes sense for your Ruby platform.
== Contributing to bychar
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.