[Pharo-users] fast subclassing/class creation in tests

Marcus Denker marcus.denker at inria.fr
Thu Oct 29 12:31:59 EDT 2015


Hi,

yes, I already felt that test runs involving unlogged code generation is very slow… can you add an entry on the issue tracker?

> On 26 Oct 2015, at 13:14, Peter Uhnák <i.uhnak at gmail.com> wrote:
> 
> 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
> 
> On Sun, Oct 25, 2015 at 12:29 AM, Robert Withers <robert.w.withers at gmail.com <mailto:robert.w.withers at gmail.com>> wrote:
> Extend Pharo byte codes to support Newspeak namespaces. #justsayin
> 
> ---
> robert
> 
> On Oct 24, 2015, at 6:22 PM, Nicolai Hess <nicolaihess at gmail.com <mailto:nicolaihess at gmail.com>> wrote:
> 
>> You can wrap the subclassing and the \removeFromSystem with
>> SystemAnnouncer uniqueInstance  suspendAllWhile: [ ]
>> 
>> 2015-10-24 20:43 GMT+02:00 Peter Uhnák <i.uhnak at gmail.com <mailto:i.uhnak at gmail.com>>:
>> Hi,
>> 
>> is it possible to do fast, non-system wide class subclassing in tests?
>> 
>> Currently I would do something like
>> 
>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> MyTest>>testSomething
>>     cls := SomeParent subclass: #Something.
>>     "... do some tests ..."
>>     cls removeFromSystem
>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> 
>> This is for example what ClassTest is doing.
>> 
>> However this is very slow, and even for small tests suite --- just ten (so far) test methods it takes over ten seconds to test it all, which is quite bad for TDD.
>> 
>> My guess is that since it has to write to class to the environment and disk and then remove it it takes a while:
>> 
>> ~~~~~~~~~~~~~
>> [ Object subclass: #Something ] timeToRun. "0:00:00:00.021"
>> [ #Something asClass removeFromSystem ] timeToRun. "0:00:00:00.526"
>> ~~~~~~~~~~~~~
>> 
>> is it possible to speed it up? Create classes that are fast to remove?
>> 
>> Thanks,
>> Peter
>> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pharo.org/pipermail/pharo-users_lists.pharo.org/attachments/20151029/c945a687/attachment.html>


More information about the Pharo-users mailing list