Xojo Workers

Xojo 2020 R2 introduced the Worker class.  The Worker is Xojo’s way to use more cores and process data faster.  This is important because the Xojo thread class is cooperative meaning that it runs on the main thread, the same one as your application, and thus shares processor time of a single core.

Why do we use threads in the first place?  Generally it’s to do a lengthy process and you don’t want the user interface to lock up.  There’s nothing more irritating from a user perspective than to have your app do nothing for a few minutes as it chugs through something.  Threads prevent this but there’s a tradeoff using them because it means the overall time it takes to do the processing is longer.  So while the app remains responsive to the user it takes longer for the processing to complete.

So the Worker class is Xojo’s attempt at multi-processing.  The Worker class actually creates a console application that is placed in the application bundle/package and handles all the work of spawning the process and passing information back and forth.

I spent some time this week banging on the two Xojo Worker examples in both Mac and Windows and found some mixed and complex results.  My quick and dirty response about Workers and how good they are is: ‘it depends’.  Let’s start talking about the examples.

My first attempt was taking the Xojo example project PictureResizer and taking it through its paces.  I tested a folder with 1071 png and jpg files.  In all tests I used compiled applications because attempting this in debug results in the Workers using threads (more on this later).  For my workers I allowed 4 cores and up to 90% core usage to stress it out.  I used my 2015 MacBookPro that’s been BootCamped to use the exact same hardware.  MacOS side is using Catalina and Windows is using Windows 10 64-bit.

My initial results were this:

Mac:  274 seconds

Win:  115 seconds

My first question was why Windows was so much faster.  So instead of using Picture.Open I switched to reading the file in via BinaryStream and then using Picture.FromData.

Mac:  182 seconds

Win:  106 seconds

Better but still quite a bit different.  I suspect that Mac console apps are using a much slower Picture library than desktop.  So I then created a thread (using default settings) and found the following:

Threads:

Mac Picture.Open:  196 seconds

Mac Binary Stream:  200 seconds

Win Picture.Open:  124 seconds

Win Binary Stream:  205 seconds

I find it surprising that Picture.Open is considerably faster on Windows than Mac.  But I was still not satisfied with this result as it seems like Workers aren’t working as expected (pun intended).  So I created a new version and passed in 20 files at a time to the Worker.

Mac Picture.Open:  196 seconds

Mac Binary Stream:  176 seconds

Win Picture.Open:  115 seconds (no difference)

Win Binary Stream:  106 seconds (no difference)

So this says to me that the example is flawed.  Only processing one picture at a time isn’t very efficient.  There is some overhead to start a Xojo console application and it seems that on macOS it’s significant enough to barely make it better than using a thread.

For test two I took the WordCount example and modified it to be able to do the same processing from a thread as well as the Worker.  I also decided to test this without using any background process just for comparison sake.  I used 1320 Text files of random length.  Test results:

Mac

Worker: 13.41 seconds

Thread:  35.53 seconds

No Thread:  34.85 seconds

Windows

Worker: 19.09 seconds

Thread:  20.04 seconds

No Thread:  25.79 seconds

I think this example is a bit better since there is a ton of string processing that obviously takes a while.  On macOS you can see that the Worker is clearly better than the Thread and even the no thread.  In Windows there is not much difference and I’m not sure how to explain this difference other than that maybe starting new processes in Windows is slow but still it’s obvious that Workers are better than no thread and slightly better than using the Thread.  With something that requires even more work I would expect this to be more pronounced.

One of the beefs I have with Workers is that you literally cannot test them in the debug environment.  When you test in the debugger you’re really working in a thread.  One of the strengths of Xojo is that working in the debugger is mostly the same as working in the real thing and Workers break that paradigm.  It’s a shame but maybe Xojo can fix this in a future release.

My other take away from using Workers is that it’s not a panacea for everything just like using Threads is not perfect.  Workers are Xojo console applications and there is overhead to starting them.  Xojo does make them easy to use by handling the inter application communications but with only string processing available you might be better off using IPCSocket communication but that’s not without its tradeoffs too.

Using Workers will take some work on your part to make sure you’re doing it as efficiently as possible.  Is it better to process a number of things in the Worker or do them one at a time?  And of course if you decide on Workers you’ll have more ‘joy’ in testing them.  Overall, ‘it depends’ on your needs to know if Workers are useful for your application.

5 thoughts on “Xojo Workers

  1. Interesting! I used a similar technique of offloading work to a console app in one of our projects. It was a lot more cumbersome to have a separate application.
    I’m kind of surprised by these results and would probably tinker with this if i had a license for desktop, haha.

  2. I don’t recall where (I thought it was somewhere on this blog – but I can’t find it) there was post about workers on Windows (I think it was by Aaron Ballman). He pointed out it is a well known fact (in Windows circles at least!) that process creation on Windows is very expensive – which is why Workers are not a great solution for multiprocessing on Windows – unless of course it is for “big” jobs).

    -Karen

    • I recall such a comment but I’ll be darned if I can find it.

      However if you google for “process start up on windows is expensive” you’ll find lots of comments and many boil down to Windows favours multithreaded models of usage over multiprocess usage.

      • Yup, that was me, in the thread (pun retroactively intended) here: https://www.bkeeneybriefs.com/2020/11/xojo-2020-release-2/#comment-8220

        Threads in Xojo are cooperative and the thread scheduler is likely one that was hand-written by people who are not threading experts (but as one of the people who worked on a Xojo thread scheduler that may or may not still be in use, I can say we tried our best). The fact that this thread scheduler performs basically the same as spawning off processes on Windows is not a good sign because the processes can utilize those extra cores in ways that the cooperative threads can’t (those are effectively pinned to a single core at a time).

        In short, the Mac numbers are closer to what I’d expect and the Windows numbers show there’s a *lot* of room for improvement on that platform.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.