[Vm-dev] Primitive 60 vs methods with more than one argument

Levente Uzonyi leves at elte.hu
Sun Oct 20 02:41:15 UTC 2013


Thanks for testing it. It looks promising.


Levente

On Sat, 19 Oct 2013, David T. Lewis wrote:

>
> On Sat, Oct 19, 2013 at 10:53:40PM +0200, Levente Uzonyi wrote:
>>
>> Hi,
>>
>> the code of primitive 60 seems to be assuming that the method has exactly
>> one argument, ignoring the actual number of arguments. This seems to be an
>> unnecessary restriction, which makes it cumbersome/impossible to use it in
>> methods which have more arguments, like #at:ifAbsent:.
>>
>> Since the primitive uses two objects from the top of the stack, it's
>> possible to write a hackish method to see the potential benefits:
>>
>> ifAbsent: aBlock receiver: receiver at: index
>>
>> 	<primitive: 60>
>> 	^aBlock value
>>
>> The primitive will treat the variable receiver as the receiver, and index
>> as the index. The real receiver is not used at all.
>>
>> This method performs 37% better than #at:ifAbsent for the case where
>> the index is valid.
>>
>> Does it have any benefits not taking the actual number of arguments into
>> account in this primitive?
>>
>> Cheers,
>> Levente
>
> I tried a rather casual benchmark. In the VM, I changed from this:
>
> commonAt: stringy
> 	"This code is called if the receiver responds primitively to at:.
> 	If this is so, it will be installed in the atCache so that subsequent calls of at:
> 	or next may be handled immediately in bytecode primitive routines."
> 	| index rcvr atIx result |
> 	index := self positive32BitValueOf: (self stackTop).  "Sets primFailCode"
> 	rcvr := self stackValue: 1.
>
> To this:
>
> commonAt: stringy
> 	"This code is called if the receiver responds primitively to at:.
> 	If this is so, it will be installed in the atCache so that subsequent calls of at:
> 	or next may be handled immediately in bytecode primitive routines."
> 	| index rcvr atIx result |
> 	index := self positive32BitValueOf: (self stackValue: argumentCount - 1).  "Sets primFailCode"
> 	rcvr := self stackValue: argumentCount.
>
>
> Then I ran the following test with each VM:
>
> (1 to: 25) collect: [:foo |
> size := 100000000.
> bigArray := Array new: size.
> 1 to: size do: [:i | bigArray at: i put: i].
> Smalltalk garbageCollect.
> Time millisecondsToRun: [1 to: size do: [:i | bigArray at: i]]].
>
> I ended up with less than 1% performance difference between the two VMs
> for the common case of #at: access to an array.
>
> This was not a very careful test, but it suggests that your idea could
> be used to improve at:ifAbsent: performance without causing significant
> performance problems elsewhere.
>
> Dave
>
>


More information about the Vm-dev mailing list