First Class Variables: speeding up reflective variable access of indexed variables

March 31, 2021 ☼ Pharo

Read and Write of indexed instance variables via the variable (an instance of IndexedSlot or a subclass) is using the mirror method on thisContext.

This way can read state from objects without sending a message to them. As the inspector uses variables for reading, it immediately can read objects without having to send a message to it. Very useful!

If we think about it, we can understand First Class Variables as a kind of specialized mirror. Other than a full Mirror object, It just knows how to read and write the variable it describes.

So right now we use the mirror primitives that are in Context and access that via thisContext:

IndexedSlot>>read: anObject
    ^ thisContext object: anObject instVarAt: index

But this means that we have to reference thisContext… which is slow.

The actual primitive methods do not care about the receiver, we can just copy them and implement them here. If we do that, we can just call the primitive method on self:

IndexedSlot>>read: anObject
    ^ self object: anObject instVarAt: index

A simple naive benchmark:

slot := Point slotNamed: #x.
[slot read: 4@4 ] bench  

before: "'12863984.406 per second'"
after: "'28472842.495 per second'"

This means this is indeed faster, while not changing the complexity of the code too much. Pull request is here