mikel/mail — pull request #681 by srawlins (2014-02-27 03:49:43+00:00)
Title: Allocate less things

With the [allocation_stats](https://github.com/srawlins/allocation_stats) gem, I tracked down the points in the mail gem where the most allocations are made. I then tried to allocate less, using the following 4 strategies:

* Either constantize or `#freeze` tiny Strings used in methods like `#gsub` and `#pack`.
* Use the bang form of Enumerable methods where safe to do so, e.g. `map!` instead of `map`.
* Replacing `foo.each_slice(2) { |a,b|` loops with `until foo.empty? a=foo.shift; b=foo.shift`

Freezing String literals should not hurt performance on Ruby < 2.1, but definitely improves performance in Ruby 2.1.x. Reducing object allocations results in applications with smaller memory footprints and less time spent in GC.

Before this pull request, running `rspec spec/mail` allocates 855k objects. This pull request reduces that count to 613k allocations.

I understand that some of these changes might upset the Rubyish feel to the library, and the elegance of the code. The maintainers might also have specific ways you want to constantize or freeze things like `"\r\n"` and `""`. Please leave comments regarding unwanted changes, and I can pull them out of this pull request.

Top allocation sites are listed [here](https://gist.github.com/srawlins/9244013). I can give more details if needed.