RuntimeLockObject - could it be faster?

Well, you can write one and surprise me. I support what I say on knowledge.

@Jeff_Tullin A more real-world example would be something like this:

Assume that foo() and bar() are arrays, not function calls, and that x is a property

Method 1

for i = 0 to iMax
  for j = 0 to jMax
     total = total + foo(i).bar(j).x
  next
next

vs.

Method 2

for i = 0 to iMax
  temp = foo(i)
  for j = 0 to jMax
     total = total + temp.bar(j).x
  next
next

The question is: which should be faster?

In theory:

  • Method 1 should be faster, because the compiler should be able to know that no reference counting is needed at all.
  • Method 2 should be slower, because the compiler does need to reference count the temp variable which holds a reference to foo(i)

In practice:

  • Method 1 is slower, and it’s clear that the compiler is reference counting everything
  • Method 2 is faster, because it has a bit less reference counting (it’s only reference counting bar(j) since foo(i) has already been done outside the loop)

Edit to add:
I’m also assuming here that Reference Counting is much slower (10x or more) than array dereferencing, which appears to be the case in the current Xojo compiler.
If as @Christian_Schmitz suggests above, RuntimeLock and RuntimeUnlock could be improved, that could easily shift the balance the other direction.

For funz, here is the disassembled code for RuntimeLockObject (x86_64 Intel):

while in theory it could be as simple as
object.referenceCount++
it appears quite a bit more complex.

RuntimeUnlockObject is about 10x as complex, but that’s understandable as it has to deal with the case when the reference count goes to zero.

The function to query the object from the object array will check bounds, read the ptr and increase reference count and then return it.

So the code in the loop always needs to unlock the references.
e.g.

for i = 0 to iMax
  temp = foo(i)
  _CheckForException
  for j = 0 to jMax
     dim _temp as something = temp.bar(j)
     _CheckForException
     total = total + _temp.x
     _DecreaseReferenceCount(_temp)
  next
  _DecreaseReferenceCount(temp)
next

maybe like this in pseudo code. After each function call is a check for an exception. And all temp objects must be released.

1 Like