FX Experience Has Gone Read-Only

I've been maintaining FX Experience for a really long time now, and I love hearing from people who enjoy my weekly links roundup. One thing I've noticed recently is that maintaining two sites (FX Experience and JonathanGiles.net) takes more time than ideal, and splits the audience up. Therefore, FX Experience will become read-only for new blog posts, but weekly posts will continue to be published on JonathanGiles.net. If you follow @FXExperience on Twitter, I suggest you also follow @JonathanGiles. This is not the end - just a consolidation of my online presence to make my life a little easier!

tl;dr: Follow me on Twitter and check for the latest news on JonathanGiles.net.

Sure, there are plenty of tips discussing how to use sequences in JavaFX, but the one I wanted to cover quickly today is regarding the fact that sequences are immutable. That is, once you create them, their content can’t change.

You lie!‘ I hear you all shout, running off to your IDE’s to show me the following fully legal and compiler-friendly code:

[jfx]
var seq = [ 1, 2, 3 ];
insert 4 into seq;
insert 5 into seq;
delete 1 from seq;

println(seq);
[/jfx]

If you run this code, the output will be [ 2, 3, 4, 5 ], as expected. It’s understandable if you think the sequence is being updated in-place – it certainly looks that way from where we’re all standing – except that under the hood it isn’t, and there are performance implications we need to be clear on. To get straight to the point, the insert and delete instructions create a brand new sequence instance, but fortunately they also ensure that the seq variable always refers to the new instance, quietly leaving the old instance to get garbage collected.

Of course, as I just noted, from a developers perspective we can treat seq as a reference to a sequence instance and be oblivious to these ‘behind-the-scenes’ sequence shenanigans. There is nothing wrong with this, but it’s important to know that creating sequences isn’t free, and certainly minimising the amount of sequences we create is a smart idea.

To be slightly more technical, I should note that there are some exceptions to this ‘sequences are immutable’ rule when dealing with non-shared sequences of specific types, but I don’t want to muddy the point of this blog, which is….

Use the expression language features of JavaFX to reduce the number of sequence instances you need to create.

For example, you might have code that looks like the following:

[jfx]
var seq:Integer[];

for (i in [1..MAX]) {
insert i*i into seq;
}
[/jfx]

I hope, with this blog post firmly at the forefront of your mind, you can now see why perhaps this isn’t such a great idea: we’re creating MAX sequence instances, one for each iteration of the for loop – ouch. Importantly, this example isn’t far-fetched and made to prove a point: I just found a very similar example in my code the other day (which I promptly fixed up), and even found a few blog posts on this site and other sites that use this approach. What you actually should do is something like the following:

[jfx]
var seq:Integer[];

seq = for (i in [1..MAX]) {
i*i
}
[/jfx]

In this case rather than create MAX instances of the sequence, we’re creating only one – the result of the for expression. This is considerably more efficient, and can lead to huge performance gains, depending on what you’re doing. In my case it made the difference between my code being usable and being jittery. Obviously in my case this was a very critical for loop, and it may be similar in your use cases also.

I hope that this helps you eek out a little more performance from your apps. Now, go forth and optimise your sequences 🙂