Category Archives: Ruby

Ruby #each .vs. #inject in the Presence of Side-Effects

Note the difference between:

numbers.inject(0) {| sum, x | sum + x }

.vs.

sum = 0
numbers.each {| x | sum += x }
sum

… the former is obviously preferred.

However:

If the #inject result value is mutated *and* the result value is used elsewhere (or implicitly returned), use a local variable with #each, instead of #inject.

Continue reading

Discrete Event Probablities

My colleague, David, had an interesting problem:

“I want to simulate exceptional events (e.g. I/O errors) at predictable rates.

For example, if an error should occur 33% of the time, it should be predictable like: ERROR, ok, ok, ERROR, ok, ok, ...

Or at 50% error rate: ERROR, ok, ERROR, ok, ...

devdriven:

“Pseudo-random function p(t) in range [0,1) at time t and P is the probability of the event (e.g. I/O error) then: event?(t) = p(t) < P.

Pseudo-random numbers are predictable if you know the seed."

David:

“Not really what I had in mind. There’s got to be a better way…”

Continue reading

Ruby: REE RUBY_HEAP allocation parameter and page alignment improvements.

http://code.google.com/p/rubyenterpriseedition/issues/detail?id=67

Use mmap() to allocate heaps by default.
Use mmap() MAP_ANON, instead of /dev/zero.
Align mmap() size to pagesize.
Align heap allocation size to pagesize.
Expand heap slotlimit to fit in aligned allocation.
New $RUBY_HEAP_* options:
  RUBY_HEAP_INIT_SLOTS=N
    initial number of slots per heap.
  RUBY_HEAP_MIN_SLOTS=N
    value is independent of RUBY_HEAP_INIT_SLOTS.
  RUBY_HEAP_MAX_SLOTS=N
    max number slots for a heap.
  RUBY_HEAP_PAGESIZE=bytes
    defaults to PAGESIZE or 4096.
  RUBY_HEAP_SLOTS_INCREMENT=N
    allow 0.
Refactor set_gc_parameters().

https://github.com/kstephens/ruby-enterprise-1.8.7-2011.03/tree/master-gc_tuning_parameter_improvements

https://github.com/kstephens/ruby-enterprise-1.8.7-2011.03/commit/692fd3c6a1d11bc6b4caeb5e167c35de7bd22d11

Ruby: Thread stack leak patch accepted into REE.

This patch reduces the stack buffer memory footprint of dead Threads as early as possible, rather than waiting until the Thread can be GCed.

This is applicable only to the zero-copy context switch patch.

http://code.google.com/p/rubyenterpriseedition/issues/detail?id=57

http://blog.phusion.nl/2011/02/12/ruby-enterprise-edition-1-8-7-2011-01-released/

ChicagoRuby Ruby Code Tweaks slides, code and video

The slides from my ChicagoRuby 2010/05/04 presentation :

http://kurtstephens.com/pub/ruby/ruby_code_tweaks/

All the raw data used to generate the graph should be referenced in the slides.

The code used to generate the slides is here:

http://github.com/kstephens/ruby_code_tweaks

I’m looking to increase the set of code “Problems” to cover other tiny code idioms and platform issues, for example: regular expressions, numerics, etc. If you have ideas, take a look at the code and contact me.

Justin Love gave a fantastic presentation on lambda and closure.

Thanks to everyone who came — hope it was helpful.

Video from the talk:

Ruby Code Performance Tweaks by Kurt Stephens from ChicagoRuby on Vimeo.

Ruby: Fixnum#gcd accepted into MRI

Ruby rational.rb clean-up and the Fixnum#gcd primitive was refactored into a new MRI extension. Fixnum#gcd is now defined during require ‘rational’.

This dramatically improves performance of Ruby Date class.

http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/ChangeLog?…

http://redmine.ruby-lang.org/issues/show/2561

See http://devdriven.com/2007/03/ruby-date-rational-fixnumgcd-hack-increased-app-performance-by-15/ .

Ruby 1.8: Improved Rational performance by 15%

This should also speed up DateTime. This will not help 1.9 performance.

The attached file is based on MRI 1.8.6 rational.rb.

 > ruby rational_performance.rb 
                                              user     system      total        real
test_it                                  32.930000   3.030000  35.960000 ( 35.971832)
test_it                                  33.840000   2.910000  36.750000 ( 36.758585)
test_it ks_rational                      29.110000   2.460000  31.570000 ( 31.572762)

Overview:

  • case x; when Foo; ...; end is faster than if Foo.kind_of?(x).
  • Avoid recuring on ephemeral objects.
  • Avoid local variables, in-line expressions.
  • Avoid return in tail position.
  • String interpolation: "#{x}/#{y}" is faster than x.to_s + "/" + y.to_s.
  • Implement #-, #zero?, #nonzero? natively.
  • #abs returns self if > 0.

MRI 1.8.7 patch to follow shortly.