Hi,
Is there a simple way to query a variable to check how many methods that access it? (just want to know the size) This works, but it is quite slow. (Morph whichSelectorsAccess: #owner) size Morph withAllSubclasses inject: 0 into: [ :sum :class | sum + (class whichSelectorsAccess: #owner) size ] Best regards, Henrik |
2015-10-01 11:18 GMT+02:00 Henrik Nergaard <[hidden email]>: Hi, I don't think there is a fast way. But you can try to work with the methods AST. (but...see below) b := Bag new. Morph methodsDo:[:m | (m ast allChildren select:[:n | n isVariable and:[n isInstance]]) asSet do:[:e | b add: e name]]. b valuesAndCounts "--> a Dictionary(#bounds->39 #color->10 #extension->37 #fullBounds->14 #owner->53 #submorphs->50 )" This does not distinguish between read and write access for variables. This is slow if the AST is not in the ASTCache, pretty fast if it is. But if you use something like "withAllSubclasses do:... with all methods ... method ast" this will fillup the ASTCache pretty fast. And an image with ast nodes for every compiled method is about ~300-400MB large.
|
In reply to this post by Henrik Nergaard
> On 01 Oct 2015, at 11:18, Henrik Nergaard <[hidden email]> wrote: > > Hi, > > Is there a simple way to query a variable to check how many methods that > access it? (just want to know the size) > > This works, but it is quite slow. > (Morph whichSelectorsAccess: #owner) size this one could be made faster by adding a #accessesField: method on CompiledMethpd to not have to call both readsField: and writeFiled (and thus decode the byte code twice on no match). But in general the approach of searching all byte code will be slow. One idea I always liked is to invest into some general “indexing” infrastructure… search indexes take memory, but they could be build on need and flushed when not used. Marcus |
In reply to this post by Henrik Nergaard
Hi Henrik,
On Thu, Oct 1, 2015 at 2:18 AM, Henrik Nergaard <[hidden email]> wrote: Hi, If it is slow then there's some mistake. Here are some measurements from the relevant code in my Spur Squeak v 5.0 image: | visited t | visited := 0. t := [self systemNavigation allMethodsSelect: [:m| visited := visited + 1. (m readsField: 66) or: (m writesField: 66)] localToPackage: #VMMaker] timeToRun. {t. visited. t * 1000.0 / visited } #(89 13553 6.566811775990556) | visited t | visited := 0. t := [self systemNavigation allMethodsSelect: [:m| visited := visited + 1. (m readsField: 6) or: (m writesField: 6)] localToPackage: #VMMaker] timeToRun. {t. visited. t * 1000.0 / visited } #(85 13553 6.271674168080867) So 85 milliseconds to analyse 13k methods, for a cost of 6 1/4 secs per method. I wouldn't call that slow. The measurements for Morph and subclasses are even better: | visited t | visited := 0. t := [self systemNavigation allMethodsSelect: [:m| visited := visited + 1. (m readsField: 66) or: (m writesField: 66)] localTo: Morph] timeToRun. {t. visited. t * 1000.0 / visited } #(34 12434 2.7344378317516487) | visited t | visited := 0. t := [self systemNavigation allMethodsSelect: [:m| visited := visited + 1. (m readsField: 6) or: (m writesField: 6)] localTo: Morph] timeToRun. {t. visited. t * 1000.0 / visited } #(34 12434 2.7344378317516487) 34 milliseconds, 2 3/4 usecs per method. This on a late 2012 Mac Mini 2.3GHz Core i7.
_,,,^..^,,,_ best, Eliot |
On Fri, Oct 2, 2015 at 11:09 AM, Eliot Miranda <[hidden email]> wrote:
Oops. This should read | visited t | visited := 0. t := [self systemNavigation allMethodsSelect: [:m| visited := visited + 1. (m readsField: 66) or: (m writesField: 66)] localTo: Morph] timeToRun. {t. visited. t * 1000.0 / visited } #(33 12434 2.654013189641306) | visited t | visited := 0. t := [self systemNavigation allMethodsSelect: [:m| visited := visited + 1. (m readsField: 6) or: (m writesField: 6)] localTo: Morph] timeToRun. {t. visited. t * 1000.0 / visited } #(34 12434 2.7344378317516487)
_,,,^..^,,,_ best, Eliot |
Free forum by Nabble | Edit this page |