Array performance, need advice please

Discussion and feedback on Construct 2

Post » Mon Jul 30, 2012 10:02 pm

Hi all,

I recently published my first app. It was written using Corona and runs on mobile devices. The app loads a database of almost 10K words, a process that takes almost 2 to 3 seconds to populate on some mobile devices. It's nearly instant on my iPad 2.

For my next app, I decided to use Construct 2 and re-use the word database. I created an array, and use AJAX to load the file (about 70K) which then populates the array with the words from the dictionary.

The logic looks like this:



This is essentially the same process that the other app is doing, however it takes nearly 10S to perform this task in Chrome on my desktop, and over a full minute to perform the same task on the iPad 2 over the wireless LAN.

Can anyone suggest any tips for increasing the performance in Construct 2? I have a few ideas I'm going to test (switching from INSERT to SET, splitting the array up into multiple arrays, etc), but before I spend all night on this I figured I'd ask the experts for other advice.

Also, will CocoonJS increase the speed of arrays on mobile devices, or is it mainly for increasing the performance of visual elements?

Unfortunately the CocoonJS Player won't work on my Samsung Tab 2 7.0 tablet so I can't do any testing to see if the increase is boosted significantly on populating the arrays on mobile or not.

Thanks for your time!
B
7
S
2
G
3
Posts: 8
Reputation: 2,738

Post » Mon Jul 30, 2012 10:46 pm

Update, changing from INSERT to SET had no effect on performance. Trying to split up the array into 4 separate arrays now to see if this has any impact.

Update #2, Broke the dictionary up into 4 files. It still takes over 30s to populate the arrays on the iPad. A noticeable improvement, which surprised me but still unplayable.

As an aside, now all of the arrays report 0 for all queries. Same exact process as above, just with 3 additional dictionary files and 3 new arrays / instance variables, and I can't get the arrays to report the values of any of the cells. We had this problem on a different project a week or so back that my partner and I worked on for a couple of days before eventually tossing in the towel. Something about working with multiple arrays seems to cause them all to break.

It could very well be a user error, but I'm just not understanding how it will work on a single array but as soon as we add the second array neither of them work any more.

I'm out of options for speed optimization short of switching from an array to a dictionary but I can't really see how that would be any quicker.jwilburn2012-07-30 23:13:53
B
7
S
2
G
3
Posts: 8
Reputation: 2,738

Post » Mon Jul 30, 2012 11:39 pm

Can you post a capx? It looks like your loop is in the wrong place. Should probably be a sub event/action as a child to the AJAX completed event.
B
21
S
5
Posts: 43
Reputation: 2,529

Post » Mon Jul 30, 2012 11:59 pm

Here's what I mean, in case you want to try it out:



See how the loop is a sub-event to the AJAX completed event?
cklester2012-07-31 00:00:19
B
21
S
5
Posts: 43
Reputation: 2,529

Post » Tue Jul 31, 2012 12:20 am

I'd say tokenat() is the bottleneck here.

I replicated your example but used a 610k text file of the english dictionary (60387 words). It was dog slow. I stopped it after 10 seconds and it only had read 1400 words.

So I modified it and used mid() and find() to progressively get the words.
http://dl.dropbox.com/u/5426011/examples13/dict.capx
It read the entire thing in 0.979 seconds.

Then for the fastest possible performance I modified the example above to save the Array to a JSON file. Then I made another capx to load it with the load from JSON action.
http://dl.dropbox.com/u/5426011/examples13/dict_json.capx
The data file is now 905k but loads in 0.039 seconds.

B
79
S
24
G
53
Posts: 4,732
Reputation: 40,227

Post » Tue Jul 31, 2012 12:58 am

@cklester - I tried your loop suggestion, but it had no affect on performance. Thanks a bunch for taking a stab at it though.

@R0J0hound - Outstanding! I tried your example and got a result of 0.07s on my laptop, 0.2s on my Tab 2, and 0.45 on my iPad2. Now to get it working in my own app.

Thanks a ton for the help. I'll post results when I get it working.
B
7
S
2
G
3
Posts: 8
Reputation: 2,738

Post » Tue Jul 31, 2012 1:08 am

@cklester - @jwilburn's events are fine, you don't need to make a subevent for the loop to work correctly. In fact sometimes adding redundant subevents can reduce performance.

@R0J0hound's suggestion of using the 'Load JSON' action is by far the best. As a rule of thumb, never do processor-intensive startup routines like this - process it once, save it to JSON, then just load the pre-processed JSON on startup. Loading JSON is done by the browser's native code (usually C++), whereas C2 events are processed by Javascript with the added overhead of the event system, which is why it can be a lot slower for this type of thing.Ashley2012-07-31 01:08:55
Scirra Founder
B
359
S
214
G
72
Posts: 22,949
Reputation: 178,544

Post » Tue Jul 31, 2012 1:56 am

The results are in. 0.006s on my laptop to load my dictionary file via JSON, 0.05s on my iPad 2 which is my slower device.

Thanks so much for the feedback. This was a ton of help.
B
7
S
2
G
3
Posts: 8
Reputation: 2,738

Post » Tue Jul 31, 2012 3:08 am

[QUOTE=Ashley] @cklester - @jwilburn's events are fine, you don't need to make a subevent for the loop to work correctly. In fact sometimes adding redundant subevents can reduce performance.
[/QUOTE]

OK, so in my example, are you saying having the loop as a sub-event is not necessary? Does the processing stop and wait for the "On 'get level definitions' completed" to complete? I thought it was like a callback, where other events are still getting processed, so if it wasn't a sub-event, it would get called. But you're saying the "json completed" is more like a loop or wait state. It WAITS until it's completed... then moves on. Right?
B
21
S
5
Posts: 43
Reputation: 2,529

Post » Tue Jul 31, 2012 1:09 pm

@cklester - see how events work. 'On completed' is a trigger which means it simply fires whenever the event happens. If a 'For' condition comes after it, it loops the rest of the event only from that point onwards (so it does not check or call the previous 'on completed' trigger at all, it just runs the loop). So using a subevent is unnecessary there.
Scirra Founder
B
359
S
214
G
72
Posts: 22,949
Reputation: 178,544

Next

Return to Construct 2 General

Who is online

Users browsing this forum: No registered users and 15 guests