By the time it gets through about 2000 objects the slowdown is noticeable. I'll try to come up with a simplified test case and script to verify things tomorrow.
-Scott. On Apr 17, 2014 8:50 PM, "Greg Clayton" <[email protected]> wrote: > How many objects are we talking about here? > > On Apr 17, 2014, at 5:46 PM, Scott Knight <[email protected]> wrote: > > > So when I call my "ruby objects" command it will create an instance of > my RubyObjects class and call invoke on it once. In the invoke is where I > have this call > > > > self.ruby_current_vm = > lldb.value(lldb.target.FindFirstGlobalVariable('ruby_current_vm')) > > > > Then in print_stats it calls into all_objects which does this > > > > > > def all_objects (self): > > self.heaps_used = self.ruby_current_vm.objspace.heap_pages.used > > > > for i in xrange(self.heaps_used): > > page = self.ruby_current_vm.objspace.heap_pages.sorted[i] > > print "page %i" % i > > > > for j in xrange(page.limit): > > rvalue = page.start[j].__getattr__('as') > > flags = rvalue.basic.flags > > yield rvalue, flags > > > > So self.ruby_current_vm should already be reused. If I stop the loop > through page.limit everything is fast, but with the code within that second > for loop things just slow down more and more. > > > > -Scott > > > > > > On Thu, Apr 17, 2014 at 8:40 PM, Greg Clayton <[email protected]> > wrote: > > Since you are dealing with a global, you are not tied to a stack frame, > so you should be able to cache this value and re-use it: > > > > > > > > if not self.ruby_current_vm: > > self.ruby_current_vm = > lldb.value(lldb.target.FindFirstGlobalVariable('ruby_current_vm')) > > > > Then you should be able to use this over and over without re-fetching > it. And you should be really fast. Each time you fetch a variable from > SBTarget::FindFirstGlobalVariable(), it re-wraps the variable in a new > VariableObjectSP which has its own cluster manager. Why? Because you might > do something like: > > > > f = lldb.value(lldb.target.FindFirstGlobalVariable('g_ptr')) > > > > f = f.a.b.c.d > > > > Now we need a reference to the ValueObjectSP for "g_ptr" (the underlying > variable that roots the entire expression) to stay alive as long as anyone > has a reference to anything that is a child of "g_ptr". Here "f" now > reference "g_ptr->a.b.c.d", so any value in this chain is correctly > reference counted using a ClusterMananger that keeps all of them alive as > long as someone has a reference to any of them. > > > > So if you reuse your "self.ruby_current_vm", you should only have a > single ClusterManager and they should stay shared as long as you use them. > Currently you are re-creating the root with each call and then referencing > a bunch of children which adds new shared references to each cluster > manager. > > > > Let me know how reusing the one instance goes. > > > > Greg > > > > > > On Apr 17, 2014, at 5:22 PM, Scott Knight <[email protected]> wrote: > > > > > I attached the instruments trace here in case it might be helpful. > Seems like a lot of time is spent in the ClusterManager. It seems like > thats called from all the ValueObject. I do realize that I'm getting values > over and over again in a loop, but it seems to just take longer each time > through the loop. I also attached the python script I'm using in the zip > file as well. > > > > > > -Scott > > > > > > > > > On Thu, Apr 17, 2014 at 7:56 PM, Greg Clayton <[email protected]> > wrote: > > > No idea. If you are running this on MacOSX, I would run a time profile > in instruments on it and see what is going on. > > > > > > On Apr 17, 2014, at 4:32 PM, Scott Knight <[email protected]> wrote: > > > > > > > Any of idea why making that call over and over again would seem to > slow down over time? > > > > > > > > -Scott > > > > > > > > On Apr 17, 2014 7:29 PM, "Greg Clayton" <[email protected]> wrote: > > > > Yep, it is the python keyword... You currently need to use your > workaround: > > > > > > > > rvalue.__getattr__("as") > > > > > > > > Glad we found it and that there is nothing wrong with the API (we > are finding children of anonymous unions, phew!). > > > > > > > > Greg > > > > > > > > On Apr 17, 2014, at 3:46 PM, Scott Knight <[email protected]> > wrote: > > > > > > > > > typedef struct RVALUE { > > > > > union { > > > > > struct { > > > > > VALUE flags; /* always 0 for freed obj */ > > > > > struct RVALUE *next; > > > > > } free; > > > > > struct RBasic basic; > > > > > struct RObject object; > > > > > struct RClass klass; > > > > > struct RFloat flonum; > > > > > struct RString string; > > > > > struct RArray array; > > > > > struct RRegexp regexp; > > > > > struct RHash hash; > > > > > struct RData data; > > > > > struct RTypedData typeddata; > > > > > struct RStruct rstruct; > > > > > struct RBignum bignum; > > > > > struct RFile file; > > > > > struct RNode node; > > > > > struct RMatch match; > > > > > struct RRational rational; > > > > > struct RComplex complex; > > > > > struct { > > > > > struct RBasic basic; > > > > > VALUE v1; > > > > > VALUE v2; > > > > > VALUE v3; > > > > > } values; > > > > > } as; > > > > > #if GC_DEBUG > > > > > const char *file; > > > > > VALUE line; > > > > > #endif > > > > > } RVALUE; > > > > > > > > > > > > > > > > > > <lldb-cpu-time.zip> > > > > > >
_______________________________________________ lldb-dev mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
