Things to avoid in Xojo

Here’s one that might be better called “Things Not To Worry About Avoiding in Xojo” from a little experimenting I did yesterday. In my mania to eke out even the most minor performance gains in this one application, and having already optimized the stuffing out of it, I decided to inline a few function calls. The functions were only 1 or 2 lines each, and they get called a lot, so I figured why not inline them, couldn’t hurt, might help? It didn’t help at all. In fact, somehow or other it made the application execute ever so slightly slower (I still don’t actually believe that’s true, but I tested it several times, and the non-inlined version executed consistently faster, and I don’t think I made any other changes).

In the same application, I changed a simple integer property — a counter — that gets checked and incremented at virtually every step of my program to a function (there’s a reason, which I won’t go into), and I was worried that might make the program significantly slower. Turns out it had no measurable impact.

My conclusion is that function call overhead in Xojo is so tiny that it’s essentially never worth worrying about. So go ahead and decompose your code into all the one- and two-line methods you want, it won’t slow it down.

you should anyway not optimize without profiling first.
because optimization without a measurement where time is needed, is a bad idea.

[quote=97498:@Garth Hjelte]Thanks Karen, perhaps I need to revisit this (rebenchmark). However, to mix the concerns, that #pragma is routine wide, so if you have a direct UI Update (non-thread) it’s REALLY not going to occur until the routine is out of scope, and that frankly sucks. But with VB that’s not a concern at all.

(I’ve been doing REAL/Xojo for a long time and it’s probably that I have preconceived notions that perhaps have faulty premises (back when I wasn’t completely aware).)[/quote]

From the LR:

Four pragma directives require that you pass True or False to turn the option on or off. Since these pragmas can be enabled or disabled, you can now do things like disable background tasks for an inner loop, but leave them enabled for the outer loop:

For y = 0 To Height #pragma BackgroundTasks False For x = 0 To Width //...process some pixels... Next #pragma BackgroundTasks True Next

[quote=97507:@Michel Bujardet]To see if the loop evaluates the end value at each loop, I tried to have a timer change the end value during a loop to stop it.
It does not seem to yield so the timer never fires until the loop is over.
As a matter of fact, on a very long loop, Xojo freezes just as bad as during While/Wend.
That is on Mac. Windows may be different.[/quote]

If your loop executes in response to an event handler then…I believe…the Timer will not fire until completion because both are on the main thread. Your comment that Xojo freezes during the loop indicates that your loop is running on the main thread.

#pragma DisableBackgroundTasks (or #pragma BackgroundTasks False) does improve loop speed, or at least it did the last time I tested it in a context with multiple threads competing for attention.

Array.Ubound may not cause a performance hit, but it’s a good idea to get in the habit of using a counter variable so that you don’t inadvertently make a call that does, i.e. myObject.MyUboundTakes20Seconds.

[quote=97594:@Christian Schmitz]you should anyway not optimize without profiling first.
because optimization without a measurement where time is needed, is a bad idea.[/quote]
True, in general, but in this case (a) I pretty much knew I was twiddling with stuff that wouldn’t make the program faster in any significant way — as I said I’d already done all the large-scale optimizations that made sense, and I was more or less just making small changes to see if I could shave off a few meaningless microseconds, and (b) the Xojo profiler is such a gawd-awful pain to use, it can sometimes be faster — and is always more pleasurable — to just make some changes and test it, profiler-be-darned.

[quote=97594:@Christian Schmitz]you should anyway not optimize without profiling first.
because optimization without a measurement where time is needed, is a bad idea.[/quote]

One of the points that really stuck out in my mind while reading Code Complete many years ago.

It’s tied to the enclosing scope. So, for example, if it’s in an ‘if’ block, it will be reset to the outer value when the scope is exited.

Thanks Joe. Good to know.

Joe, maybe you should check documentation and verify that your info is correct and than update docs & examples?
http://documentation.xojo.com/index.php/Pragma_Directives

I cleaned up the pragma page a bit based on this information.

Paul, your example:

For y = 0 To Height
#Pragma BackgroundTasks False
For x = 0 To Width
//...process some pixels...
Next

#Pragma BackgroundTasks True
Next

is how I ever understood it should work.

But I understood Joe’s statement like:

#Pragma BackgroundTasks False
// Stop background processing
If True then // Open a new scope
  #Pragma BackgroundTasks True
  // Background tasks are ok here
  doSomeProcs()
End If
// Background tasks returned to the outer state False? <-- ???
doMoreTasks()

Confirm this behavior please.

“We should forget about small efficiencies, say about 97% of the time; premature optimization is the root of all evil” – Donald E. Knuth; McConnell mentions this many times in the book. I sure remember it too - it’s nice because I can major on the majors and minor on the minors.

Here’s a link taking a contrarian view; but not really, he’s just qualifying the statement. It’s still completely true.

It’s sort of obvious - shaving off 100ms when all is said and done isn’t worth the time.

Thanks Paul.

[quote=97665:@Garth Hjelte]Here’s a link taking a contrarian view; but not really, he’s just qualifying the statement. It’s still completely true.

http://joeduffyblog.com/2010/09/06/the-premature-optimization-is-evil-myth/ [/quote]

Interesting read… I especially liked the quote:

“Most programmers have seen them, and most good programmers realize they’ve written at least one.
They are huge, messy, ugly programs that should have been short, clean, beautiful programs.”

As Dewey Cox once said, “guilty as charged”

This is such a simple workaround to such an expensive routine I’m surprised it’s not officially recommended in the NthField and CountFields guide entries.

NthField and CountFields have the doubtful honor of being ridiculously intuitive (in name and use). They become like crutches you forget how to walk without. When you hit one of the scenarios where they really show their ugly face you’re surprised it took so long to realize.

Can someone clarify what effect the “DisableBackgroundTasks” has on a web app? Does it just disable the tasks associated with that session or across the app? What if you are using special URLs what is then the scope of the disable?

DisableBackgroundTasks disables switching to other threads. As each session has a thread, other sessions will stop working for the time the background tasks are stopped.

In which case maybe the docs should warn “strongly” about using this in web apps because that is the last thing you would want to do in a web app. In fact I would say that is a bit like a “doEvents” and maybe should be removed from the WE framework.