Skip to content

Commit

Permalink
Introduce GC'able cache for Roo::Excelx::Extractor#doc
Browse files Browse the repository at this point in the history
Memory Profiling script:
```
MemoryProfiler.report{Roo::Excelx.new('test/files/Bibelbund.xlsx').tap{|x|(2..x.last_row).each{|i| x.row(i)}}}.pretty_print

```

Benchmark Script:
```
puts Benchmark.measure{ Roo::Excelx.new('test/files/Bibelbund.xlsx').tap{|x|(2..x.last_row).each{|i| x.row(i)}} }
```


Result on Master:
```
Total allocated: 37131810 bytes (517026 objects)
Total retained:  5562913 bytes (103010 objects)

allocated memory by gem
-----------------------------------
  19288066  roo/lib
  11049821  nokogiri-1.8.4
   6792403  rubyzip-1.2.2
      1304  tmpdir
       216  other

retained memory by gem
-----------------------------------
   5560934  roo/lib
       782  rubyzip-1.2.2
       725  nokogiri-1.8.4
       296  tmpdir
       176  other

  0.720000   0.020000   0.740000 (  0.733750)
```

Result after patch:
```
Total allocated: 34561842 bytes (504998 objects)
Total retained:  5563553 bytes (103026 objects)

allocated memory by gem
-----------------------------------
  19254338  roo/lib
   8513101  nokogiri-1.8.4
   6792403  rubyzip-1.2.2
      1304  tmpdir
       320  weakref
       216  other
       160  ref-2.0.0

retained memory by gem
-----------------------------------
   5561094  roo/lib
       782  rubyzip-1.2.2
       725  nokogiri-1.8.4
       320  weakref
       296  tmpdir
       176  other
       160  ref-2.0.0

  0.610000   0.010000   0.620000 (  0.618642)
```


Note:
Ruby does have native implementation of WeakRef. But I've choosed to go with 'ref' gem for this following reason:
	https://github.com/ruby-concurrency/ref#problems-with-weakref
  • Loading branch information
chopraanmol1 committed Sep 18, 2018
1 parent ced9c5c commit c939c01
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
24 changes: 21 additions & 3 deletions lib/roo/excelx/extractor.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# frozen_string_literal: true

require "ref"

module Roo
class Excelx
class Extractor

COMMON_STRINGS = {
t: "t",
r: "r",
Expand All @@ -21,14 +22,31 @@ def initialize(path, options = {})
private

def doc
raise FileNotFound, "#{@path} file not found" unless doc_exists?
instance_cache(:@doc) do
raise FileNotFound, "#{@path} file not found" unless doc_exists?

::Roo::Utils.load_xml(@path).remove_namespaces!
::Roo::Utils.load_xml(@path).remove_namespaces!
end
end

def doc_exists?
@path && File.exist?(@path)
end

def instance_cache(key)
object = nil

if ref = instance_variable_get(key)
object = ref.object
end

unless object
object = yield
instance_variable_set(key, Ref::WeakReference.new(object))
end

object
end
end
end
end
1 change: 1 addition & 0 deletions roo.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
spec.require_paths = ['lib']

spec.add_dependency 'nokogiri', '~> 1'
spec.add_dependency 'ref', '~> 2'
spec.add_dependency 'rubyzip', '>= 1.2.1', '< 2.0.0'

spec.add_development_dependency 'rake', '~> 10.1'
Expand Down

0 comments on commit c939c01

Please sign in to comment.