If() and if..then speed differences

I know and learned a lot of it too. :slight_smile:

1 Like

what bout instrb v.s.the API 2.0 equivalent?

I believe that Swift defaults to immutables and its just a question of assigning a pointer, but Xojo defaults to mutables and needs “copies” of values, and making that takes clock ticks.

3 Likes

That was one of the hardest things to get my head around when learning Objective-C, immutable objects. I hated it.

2 Likes

:laughing: I know that Xojo users would too.
But immutables are today the State of the Art of value declarations and languages have things like let and var to differentiate them instead of just var or Dim or whatever in the past. The current law is, constants and immutables everywhere, mutables where is needed.

1 Like

<https://xojo.com/issue/65918>

UTF8 scans done right have higher cost than fixed bytes standards like ISO8859-1, maybe ParseDate were using a “relaxed scan” (assuming a set of one byte chars) right in C and now they use a more complete (correct but heavier) UTF8 lib for the job do calls for this lib adding an overhead. If I do remember correctly, many string handlings were changed to make a better/proper use of current UTF8 standards.

What is the benefit? I read a dictionary, make it mutable, edit it and copy it back to the original dictionary. I had to do that with CFDictionaryMBS in the last days for a LaunchAgent.

Speed and Size and less prone to dev errors and NOEs.

If you declare (depends on your compiler) n identical constant values in your code, in memory the compiler could solve them all as just one value in memory. If immutables all the processing may be pointer based many times not needing copies and not null once you guaranteed the initialization. The compiler can always favor speed and size where mutables can’t.

1 Like

This is excellent sleuthing. Thank you Christian Schmitz.

I did a little bit more testing this AM, using some additional types (“Date”, “Double”, “DateTime”).

For what it’s worth… In my testing, the only conditions where the inline version of “If” seems to be slower is when a “String” is involved. (matching Christian’s findings)

Assigning a “String” to a “Variant” was exceptionally slow, but assigning an “Integer” to a “Variant” was still quicker using the inline version of “If”

For every other type I tested, the inline version of “If” was quicker.

Sample Project: Dropbox - sample_project.xojo_binary_project.zip - Simplify your life

Some examples:


(string is slower)


(assigning a string to a variant is MUCH slower)

2 Likes

Be aware there also may be big platform differences, e.g. <https://xojo.com/issue/65723>

  • String.Characters Iterator is 1000x slower on Windows than macOS
2 Likes

There’s a dropbox link above for the sample project I put together if anyone feels like running it on Windows. (or Linux!)

The project is 2021 r2.1 project, fyi.

I ran this project on macOS as a build, and here as Christian predicted the explicit If version is always leading or on par with inline. Inline is only faster in a debug build.
String and Variant(String) times differ enormously with explicit leading in every case.

In a Windows 10 build results are quite similar to macOS (even sometimes twice as fast in Parallels as on the host Mac system), with the exception of inline variant being a bit faster, but double and integer inline will not finish?!?!

EDIT: The latter stops when the loop counter is increased > 10 Mill. – ternary tests do exit correctly.

EDIT II: Posted some thread findings I did not expect here.

A little additional information. OS version and processor (at least on Mac) also seem to affect performance.

On a M1 mini on Big Sur, inline was generally faster (with the exception of working with strings) at lower counts. (e.g. on the M1 mini, 10M loops when setting an Integer was faster than explicit)

This advantage decreased as you upped the number of loops, but…

I’d say in general, the performance difference between inline and explicit is immaterial for typical uses, *except when you’re working with the String type.

Working with Strings shows materially worse performance when using the inline/trinary version of “If”.

If you are doing a large amount of conditional logic operations which are setting String variables, the inline version of If() should (in my opinion) be avoided until its performance is brought inline with the explicit, If…Then, version of “If”.

(p.s. this seems to be true regardless of optimization level set when compiling the testing application)

Cause internally they seem to use Text which has always been slower. CPU diffrences will always be there, maybe xojo could ditch the Text type alltogether in the in-line if we should see some improvements there.

Wasn’t Text deprecated?

Yes it is but xojo still uses it aparently, which is kinda… you know … slow (especially on windows).
see here: MBS Blog - If vs If in Xojo

Assuming nothing has changed in this area of the compiler…

The If() expression is an operator and has to be to avoid evaluating the not-chosen expression. The overhead with strings only occurs if both value expressions are quoted literals.

The short version of “why” is that the compiler has to choose a type for quoted literals (String vs Text). In most cases this is obvious from the context that the literal is used in, but the compiler doesn’t know when compiling the If operator what the result should be and just defaults to Text. Then when it gets used as a String it has to do a conversion.

Ideally the compiler wouldn’t have the complexity of deciding the type of quoted literals, but that ship has sailed. One option would be to change If to prefer the result type to be String for quoted literals but changing the semantics could break things in subtle ways – perhaps ways that nobody cares about at this point. Another option would be to have an optimization pass that cleans up the generated LLVM IR by finding calls to RuntimeStringFromText that take a Text literal and replacing it with an equivalent String literal.

20 Likes

Good to hear from you Joe.

6 Likes