On Wed, Apr 12, 2017 at 10:51 AM, Denis Kudriashov <dionisi...@gmail.com> wrote:
> Hi. > > I profiled a bit and found problem: > > PharoClassInstaller>>migrateClasses: old to: new using: > anInstanceModification > instanceModification := anInstanceModification. > old ifEmpty: [ ^ self ]. > [ > 1 to: old size do: [ :index | > self updateClass: (old at: index) to: (new at: index)]. > old elementsForwardIdentityTo: new. > " Garbage collect away the zombie instances left behind in garbage memory > in #updateInstancesFrom: " > " If we don't clean up this garbage, a second update would revive them > with a wrong layout! " > " (newClass rather than oldClass, since they are now both newClass) " > Smalltalk garbageCollect. > ] valueUnpreemptively > > Commenting garbage collection here increases performance 10 times. > Then commenting class update loop increases performance 3 times more. But > this loop is required. It adopts all instances of old class to new one. And > time here spent in #allInstances method. > > Can we remove manual garbage collection here? Why it is needed? > Well, there is the comment that explains it and makes pretty good sense. > > 2017-04-12 9:34 GMT+02:00 Peter Uhnak <i.uh...@gmail.com>: > >> Hi, >> >> does anyone know why adding instance variables is so slow? >> >> I did some quick benchmarks (see below), resulting in more than order of >> magnitude speed difference between having it in the class definition and >> adding it later. >> >> In fact it is still much faster to delete the class and then recreate it >> with the instance variables in the d efinition. For four arguments it is >> till 8x faster to delete the class four times and recreate it then just add >> the variable. Unfortunately I cannot just trash the classes (they have >> methods and inheritance). >> >> So the question is: why is it so slow? can I somehow improve the >> performance? >> >> Thanks, >> Peter >> >> >> Benchmarks: >> >> >> [ >> cls := Object subclass: #Some1. >> cls removeFromSystem. >> ] bench. "'91 per second'" >> >> [ >> cls := Object subclass: #Some2 instanceVariableNames: 'variable'. >> cls removeFromSystem >> ] bench. "'90 per second'" >> >> [ >> cls := Object subclass: #Some3. >> cls addInstVarNamed: 'variable'. >> cls removeFromSystem. >> ] bench. "'7 per second'" >> >> [ >> cls := Object subclass: #Some4. >> cls removeFromSystem. >> cls := Object subclass: #Some4 instanceVariableNames: 'variable'. >> cls removeFromSystem. >> ] bench. "'43 per second'" >> >> >> >> >> [ >> cls := Object subclass: #Some3. >> cls addInstVarNamed: 'variable1'. >> cls addInstVarNamed: 'variable2'. >> cls addInstVarNamed: 'variable3'. >> cls addInstVarNamed: 'variable4'. >> cls removeFromSystem. >> ] bench. "'2 per second'" >> >> [ >> cls := Object subclass: #Some4. >> cls removeFromSystem. >> cls := Object subclass: #Some4 instanceVariableNames: 'variable1 >> variable2 variable3 variable4'. >> cls removeFromSystem. >> ] bench. "'44 per second'" >> >> [ >> cls := Object subclass: #Some5. >> cls removeFromSystem. >> cls := Object subclass: #Some5 instanceVariableNames: 'variable1'. >> cls removeFromSystem. >> cls := Object subclass: #Some5 instanceVariableNames: 'variable1 >> variable2'. >> cls removeFromSystem. >> cls := Object subclass: #Some5 instanceVariableNames: 'variable1 >> variable2 variable3'. >> cls removeFromSystem. >> cls := Object subclass: #Some5 instanceVariableNames: 'variable1 >> variable2 variable3 variable4'. >> cls removeFromSystem. >> ] bench. "'17.269 per second'" >> >> >