From: Paul Brannan Date: 2010-01-11T23:52:07+09:00 Subject: [ruby-core:27536] Re: better GC? On Fri, Dec 11, 2009 at 06:55:53AM +0900, Roger Pack wrote: > Could I put in a small plea for a better GC? > > With this code: > > (1..7).each{|n| puts n; a = ['a']*(10**n); a.inspect;} > > when n gets high enough almost 50% of the time is spent in GC. > Somewhat frustrating. I modified this program slightly (imo cases n=1..6 aren't useful for a profile): pbrannan@random:~/tmp> cat test.rb 100.times do |n| puts n a = ['a']*(10**6) a.inspect end The results aren't at all surprising. Callgrind reports 52% of the application's run time is spent in gc_mark. 21% of the time is spent in gc_mark_children, which means the majority of the time the objects are immediate objects or have already been marked (I'm guessing the latter in this program). This probably isn't very representative of a real-world application due to the small number of objects, but the large size of the array. It makes me think two things though: 1. Is gc_mark getting inlined? If it were, marking the array could be done without so many function calls. 2. If there were many objects, what would be the cost of resetting the FL_MARK flag on all the objects in gc_sweep? Could this cost be eliminated by using a 2-bit counter instead of a single flag? RBASIC(v)->flags = 0 /* when the object is created */ counter = ((counter + 1) % 3) + 1; /* before marking */ if (p->as.basic.mark_counter == counter) /* to check if marked */ p->as.basic.mark_counter = counter; /* to mark */ ; /* no need to reset all the flags at the end now */ Hoping to spark some thought/discussion, Paul