Thanks Nicolai, the suspension seems to have quite a significant performance impact.
Out of curiosity I did some benchmarking. Although the numbers seems to vary a lot based on something (the size of the image jumped from 25 to 40MB after I was done... and there seems to be some correlation with the performance). Repeatedly running a benchmark seems also detrimental as the performance can drop by over 30%... so probably it would be best to run each benchmark in a completely new image...
However the fact that the performance decreases over time is problematic, because that means that running the test suite will get worse over time.
I find it also peculiar to see that unlogged anonymous classes are faster when the announcer is NOT suspended.
And while for classes the improvement was ~40x, for methods it was over 200x faster... so I guess the best way is to modify performTest behavior to something like
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MyTestClass>>performTest
SystemAnnouncer uniqueInstance suspendAllWhile: [ super performTest ]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Benchmarks (I've removed decimal parts and thousand separators because they are always confusing me):
Class creation with announcer:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[ |cls|
cls := Object subclass: #Something.
cls removeFromSystem.
] bench. "'9 per second'"
[ |cls|
cls := Object subclass: #Something.
cls removeFromSystemUnlogged.
] bench. "'173 per second'"
[ |cls|
cls := Object newAnonymousSubclass.
cls removeFromSystem.
] bench. "'4 per second'"
[ |cls|
cls := Object newAnonymousSubclass.
cls removeFromSystemUnlogged.
] bench. "'512 per second'"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Class creation without announcer:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[ SystemAnnouncer uniqueInstance suspendAllWhile: [ |cls|
cls := Object subclass: #Something.
cls removeFromSystem.
] ] bench. "'371 per second'"
[ SystemAnnouncer uniqueInstance suspendAllWhile: [ |cls|
cls := Object subclass: #Something.
cls removeFromSystemUnlogged.
] ] bench. "'351 per second'"
[ SystemAnnouncer uniqueInstance suspendAllWhile: [ |cls|
cls := Object newAnonymousSubclass.
cls removeFromSystem.
] ] bench. "'368 per second'"
[ SystemAnnouncer uniqueInstance suspendAllWhile: [ |cls|
cls := Object newAnonymousSubclass.
cls removeFromSystemUnlogged.
] ] bench. "'430 per second'"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Methods with announcer:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cls := Object subclass: #Something.
[
cls compile: 'method ^ 1'.
] bench. "'9 per second'"
anon := Object newAnonymousSubclass.
[
anon compile: 'method ^ 1'.
] bench. "'9 per second'"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Methods without announcer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cls := Object subclass: #Something.
[ SystemAnnouncer uniqueInstance suspendAllWhile: [
cls compile: 'method ^ 1'.
] ] bench. "'1814 per second'"
anon := Object newAnonymousSubclass.
[ SystemAnnouncer uniqueInstance suspendAllWhile: [
anon compile: 'method ^ 1'.
] ] bench. "'2063 per second'"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Peter