Improving load Times
Sometimes projects in Flowstone can be slow to load. Back in the days of Synthmaker this was quite a problem, nowadays load times are much better but sometimes depending on the schematic it can still be slow. This article will cover the main areas you need to be optimizing. I will provide some test schematics so you can see the differences for yourself (get your stop watch ready!). These test schematics will sometimes be “over the top” (not a real world example ) they are meant as “stress tests” the aim is to push things to the limit so we can see what really improves load times.
There has been plenty of hear say over the years about what can cause slow load times, sometimes without any real proof. This article will stop you from doing things that have no effect and get you straight onto the things that do, so lets get on with it!
Don’t make your modules hierarchy too deep
Modules are incredibly useful for organizing our schematics, but if you are creating too many deeply nested modules this can have a negative effect on load times. Here is an example Deep Levels, inside you will find many modules with very deep module hierarchies, at the bottom of each is a single float component.
Now compare this one One Level, that too contains a single float component but it is only one level deep. Hopefully you can noticed the difference. The deep levels schematic takes 2 seconds to load on my PC while the other is instant. Consider this, the schematic is doing NOTHING and is only 6KB in size and it is taking 2 seconds!
Please don’t stop using modules though! Just be aware that many deeply nested modules can have a negative effect on load time. If you only have a small handful of deeply nested modules then do not expect to see a noticeable improvement, so it is probably not worth the effort in small cases.
Avoid the use of index selectors, with large lists
Index selectors are no longer used in any of the Ruby based components that come with Flowstone. Index selectors are used to display a list of options in a drop down menu on the properties panel. It was used in all the old primitive based components. If you are using the old primitive based components I would not go deleting all the index selectors. The only case where I would delete them is in cases of very large lists of options because this is where the real slow down comes.
It was once assumed that the System fonts primitive would cause slow load times, I can show that is not the case. See this schematic System font primitives, this contains 144 System font primitives and loads in under half a second on my PC and I have 1232 fonts on my system.
Now try this one that has an index selector connected to each one, System font with index selector. That loads in about 2.2 seconds on my PC. So it is clear to see that the extra loading time really comes from the index selector. The more fonts on the system the slower the one with index selectors will load.
Back when Flowstone was called Synthmaker load times was a real issue, this was one of the main causes, some people where reporting load times of upwards of 30 seconds. I’m betting they had a lot of fonts on their system (thousands) and the index selector was slowing it right down.
Prefer Ruby based components over primitive ones
Ruby based components should usually load much faster than primitive based ones. Compare the load time of this schematic containing 500 primitive based knobs 500 Primitive knobs, with this one based in Ruby 500 Ruby knobs.
There are actually many reasons why the Ruby knobs are faster. One of the reasons is module depth. Primitive based components tend to have a much deeper hierarchy than their Ruby counterparts. Another is Rubys interpreter, which is very fast. Ruby also doesn’t use triggers like primitives do, many components fire triggers on load which can cause everything to recalculate, often unnecessarily. Ruby components also do not use index selectors, so all of this adds up to the Ruby based components loading much faster.
One problem with using Ruby based components (well the knobs at least) is they are not quite as feature rich as the old primitive ones, so if you need certain features such as ‘snap’ then you may have to stick with the old versions.
Beware of after load triggers
There is a component called “After Load” which gives us a trigger which can be useful in some situations. Beware of triggering anything that involves heavy processing, your project will not load until this processing has completed. It is also important to know that some other components output their own “After Load” trigger.
- Preset Parameter Array
- Sample Rate
- Wavetable Create
There could be more, but these are the ones I am aware of.
This is important to know because you could be doing extra processing during load and not even know it.
Take this example from the wave draw oscillator that comes with Flowstone….
Can you spot the problem? The wavetable is created twice on load! Why? because the wavetable is created automatically on load (first create) and then a trigger is sent again to the create input forcing it to be recreated again. This is because of the Preset Parameter Array which outputs its own trigger on load.
Here is the correct way to do it… Wavetable correct . Here I avoid getting a trigger from the array and get it directly from the drag component.
So be aware that these components could be causing extra processing and adding to load times.
Avoid very large wavetables
The larger the wavetable the longer the load time of your synth or effect. It is a trade off, very large wavetables will make a very rich, nice sounding oscillator but will add significantly to load times. I find that a table size of 1024 is about right. But if you are prepared to go lower this will save a noticeable amount of load time.
Don’t store large amounts of data in Text components, prefer arrays where possible.
It is common to see waveforms stored inside text components for use with the wavetable create. This can add noticeably to load times if the waveform is large and there are many (ie hundreds). The reason being is that all the data in the text component has to be converted to a float array, this is noticeably slow for large arrays and should be avoided. Instead store the data as an array avoiding the conversion.
Here is a schematic which contains 1200 text components being passed to an array, Text to array . Each text file contains 4096 zeros, this is just to simulate a large waveform (the zeroes don’t matter).
Now here is the same schematic but without using text components, Just array. This one should be faster because now there is no conversion to float array happening on load. You may not be passing a text component directly to an array component like this, but even if you just pass it to an array output connector, the conversion is still happening.
Limit the number of controls in your project
This should be obvious from the 500 knobs test done earlier. Limit the amount of controls in your project. Ask yourself do I really need to expose this functionality? Or maybe you have a Synth that has 5 oscillators, each oscillator section might have 10 controls (fine,semi,octave,waveform,phase ect…) do you really need 5 oscillators? Maybe 3 would be OK and hence with that you could just have reduced by 20 controls.
Limit the amount of data such as images and wave files stored inside your project
This one is not practical for me to do stress tests because of the resulting file sizes, but keep your schematic size to a minimum. Only package what is absolutely necessary in your schematic. You may want to include a few wave files in the schematic, this is fine, but if you are shipping a large sound bank with the VST then make that separate and don’t include it in the schematic.
Also consider creating a background image which contains as much of the GUI elements built into it as possible such as Labels beneath controls or the controls themselves (this works for static knobs). This can save many different images being loaded. One image will load faster than many different ones, and will reduce file size.
I have done some tests of wireless links and these tests show that wireless links can actually improve load times. I changed the Deep levels schematic to use wireless links instead of normal links and load time halved and is now nearly instant! Check it out Deep Levels wireless. For easy reference here is the original Deep levels from earlier in the article Deep Levels.
This is not conclusive but it does show that wireless links can actually help with load times, at least in this case. There could be cases where it proves slower, I will have to think up some more types of test for it to be conclusive. But I suspect that previous assumptions that wireless links add to load times are not correct, at least not always.
My reasoning for the wireless version of Deep Levels to load faster is the lack of input components in the schematic. In the original example there was literally thousands of input components (320 per level). So with the use of wireless we are actually removing the need for many components. This reduction is obviously giving a more positive contribution than any potential negative effect of using wireless.
This means the real cost of wireless is hard to judge but the benefits (less components) would seem to override any potential costs.
That it for now…
Hopefully this article has been of some use and now you know a few things about how to keep load times respectable.
If I have overlooked anything or you know of some other areas that can be improved let me know in the comments and I will update the article!