rubyzip/rubyzip — pull request #133 by srawlins (2014-02-06 22:49:06+00:00)
Title: Freeze static strings used when writing a zipfile

As mentioned in rubyzip/rubyzip#130, `#freeze` many static Strings in `entry[_set].rb`, `extra_field.rb`, and `file.rb` for better performance in ruby >= 2.1. Performance should not be hindered in ruby < 2.1.

Performance is improved by reducing the number of String allocations that need to occur, thus reducing GC time. Here is a before and after:

### master

```
$ ruby rubyzip_write.rb | grep "String"
sourcefile sourceline class count
--------------------------------------------------------- ---------- --------------- -----
/Users/srawlins/code/rubyzip/lib/zip/entry_set.rb 80 String 10050
/Users/srawlins/code/rubyzip/lib/zip/extra_field.rb 67 String 7000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 365 String 5044
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 265 String 4000
/Users/srawlins/code/rubyzip/lib/zip/entry_set.rb 21 String 3840
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 107 String 3000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 62 String 2000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 48 String 2000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 254 String 2000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 273 String 2000
/Users/srawlins/code/rubyzip/lib/zip/deflater.rb 20 String 2000
/Users/srawlins/code/rubyzip/lib/zip/extra_field.rb 73 String 2000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 434 String 2000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 63 String 2000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 275 String 1920
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 458 String 1000
/Users/srawlins/code/rubyzip/lib/zip/file.rb 261 String 1000
/Users/srawlins/code/rubyzip/lib/zip/central_directory.rb 29 String 1000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 360 String 1000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 301 String 1000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 355 String 1000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 367 String 1000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 637 String 1000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 181 String 1000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 54 String 1000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 513 String 1000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 378 String 1000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 411 String 1000
...
# totalling 63854 allocations from these locations
```

### this pull request

```
$ ruby rubyzip_write.rb | grep "String"
sourcefile sourceline class count
--------------------------------------------------------- ---------- --------------- -----
/Users/srawlins/code/rubyzip/lib/zip/extra_field.rb 67 String 7000
/Users/srawlins/code/rubyzip/lib/zip/entry_set.rb 80 String 5050
/Users/srawlins/code/rubyzip/lib/zip/entry_set.rb 21 String 3840
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 365 String 3044
/Users/srawlins/code/rubyzip/lib/zip/extra_field.rb 73 String 2000
/Users/srawlins/code/rubyzip/lib/zip/deflater.rb 20 String 2000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 273 String 2000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 265 String 2000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 275 String 1920
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 378 String 1000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 434 String 1000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 458 String 1000
/Users/srawlins/code/rubyzip/lib/zip/central_directory.rb 29 String 1000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 513 String 1000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 367 String 1000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 360 String 1000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 181 String 1000
/Users/srawlins/code/rubyzip/lib/zip/entry.rb 355 String 1000
...
# totalling 37854 allocations from these locations
```

GC time is down too:

```
GC 16 invokes.
Index Invoke Time(sec) Use Size(byte) Total Size(byte) Total Object GC Time(ms)
1 0.220 1328360 3688320 92208 4.9319999999999915
2 1.118 19905120 37389120 934728 86.0360000000000013
3 1.686 19906480 37389120 934728 35.1129999999999498
```

vs

```
GC 16 invokes.
Index Invoke Time(sec) Use Size(byte) Total Size(byte) Total Object GC Time(ms)
1 0.221 1328360 3688320 92208 5.6819999999999923
2 1.032 15745440 30094080 752352 77.9510000000001070
3 1.506 15746800 30094080 752352 30.0819999999999438
```