obiot
February 14, 2023, 2:03am
1
Using the new sprite-based performance test at GitHub - Shirajuki/js-game-rendering-benchmark: Performance comparison of Javascript rendering/game engines: Three.js, Pixi.js, Phaser, Babylon.js, Two.js, Hilo, melonJS, Kaboom, Kontra, Canvas API and DOM! , I spent some time comparing the latest 14.5 version of melonJS with the previous one to understand how much improvements we managed to pack into that version.
Globally the 14.5 version brings an average 20% performance improvements for both Sprite and Primitive rendering (running on a M1 Max laptop), bringing melonJS on par (at 60fps while drawing 10’000 sprites, knowing we are capped at 60fps) with other framework like Phaser or Pixi for sprite rendering.
For primitive drawing, especially with circles, we are still “a bit” behind when drawing more than 500 circles per frame, but that should be fixed with this ticket : fix batch drawing for primitive shapes · Issue #1172 · melonjs/melonJS · GitHub
14.4.0
14.5.0
Stroke
500 op/s
60 fps
60 fps
1000 op/s
60 fps
60 fps
2500 op/s
31 fps
48 fps
5000 op/s
14 fps
22 fps
10000 op/s
8 fps
10 fps
Fill
500 op/s
45 fps
60 fps
1000 op/s
21 fps
30 fps
2500 op/s
9 fps
12 fps
5000 op/s
4 fps
6 fps
10000 op/s
3 fps
4 fps
Sprite
500 op/s
60 fps
60 fps
1000 op/s
60 fps
60 fps
2500 op/s
60 fps
60 fps
5000 op/s
60 fps
60 fps
10000 op/s
50 fps
60 fps
Perf Inc
Stroke
10000 op/s
n/a
25%
Fill
10000 op/s
n/a
25%
Sprite
10000 op/s
n/a
17%
(Note: at the time of this writing, the online version used by the benchmarking tool has not been updated yet with melonJS 14.5).
I’ll keep this topic pinned as a place to keep track of progress and improvements in terms of performances.
obiot
March 18, 2023, 3:41am
3
Following the 15.0.0 release, here is some updated benchmark.
The focus on this last release was on properly enabling batch drawing for primitives shapes, which allows us here to gain up 81% performances improvements for rectangle and polygon based shapes (circle and friends are still a very different animal when it comes to rendering in WebGL).
Anyway, over the last 2 versions, huge improvements across the board !
(M1 Max)
14.4.0
14.5.0
15.0.0
Stroke (circle)
500 op/s
60 fps
60 fps
60 fps
1000 op/s
60 fps
60 fps
60 fps
2500 op/s
31 fps
48 fps
60 fps
5000 op/s
14 fps
22 fps
32 fps
10000 op/s
8 fps
10 fps
16 fps
15000 op/s
5 fps
7 fps
10 fps
Stroke (rect)
500 op/s
60 fps
60 fps
60 fps
1000 op/s
60 fps
60 fps
60 fps
2500 op/s
60 fps
60 fps
60 fps
5000 op/s
37 fps
40 fps
60 fps
10000 op/s
15 fps
18 fps
60 fps
15000 op/s
10 fps
10 fps
60 fps
Fill (circle)
500 op/s
45 fps
60 fps
60 fps
1000 op/s
21 fps
30 fps
32 fps
2500 op/s
9 fps
12 fps
12 fps
5000 op/s
4 fps
6 fps
6 fps
10000 op/s
3 fps
4 fps
4 fps
15000 op/s
2 fps
2 fps
3 fps
Fill (rect)
500 op/s
60 fps
60 fps
60 fps
1000 op/s
60 fps
60 fps
60 fps
2500 op/s
33 fps
35 fps
60 fps
5000 op/s
15 fps
16 fps
60 fps
10000 op/s
6 fps
6 fps
32 fps
15000 op/s
4 fps
4 fps
21 fps
Sprite
500 op/s
60 fps
60 fps
60 fps
1000 op/s
60 fps
60 fps
60 fps
2500 op/s
60 fps
60 fps
60 fps
5000 op/s
60 fps
60 fps
60 fps
10000 op/s
50 fps
60 fps
60 fps
15000 op/s
30 fps
37 fps
37 fps
Perf Inc
Stroke (circle)
10000 op/s
n/a
25%
38%
Stroke (rect)
10000 op/s
n/a
15%
71%
Fill (circle)
10000 op/s
n/a
25%
0%
Fill (rect)
10000 op/s
n/a
3%
81%
Sprite
10000 op/s
n/a
17%
0%
Sprite
15000 op/s
n/a
19%
0%
obiot
May 23, 2023, 2:46am
4
with the last 15.3.0 version, we are now able to render 15’000 sprites at 60 fps, which is now at least double the performance compared to the 14.4 version few months ago :
(M1 Max / Chrome)
14.4.0
14.5.0
15.0.0
15.3.0
Stroke (circle)
500 op/s
60 fps
60 fps
60 fps
60 fps
1000 op/s
60 fps
60 fps
60 fps
60 fps
2500 op/s
31 fps
48 fps
60 fps
60 fps
5000 op/s
14 fps
22 fps
32 fps
37 fps
10000 op/s
8 fps
10 fps
16 fps
16 fps
15000 op/s
5 fps
7 fps
10 fps
11 fps
Stroke (rect)
500 op/s
60 fps
60 fps
60 fps
60 fps
1000 op/s
60 fps
60 fps
60 fps
60 fps
2500 op/s
60 fps
60 fps
60 fps
60 fps
5000 op/s
37 fps
40 fps
60 fps
60 fps
10000 op/s
15 fps
18 fps
60 fps
60 fps
15000 op/s
10 fps
10 fps
60 fps
60 fps
Fill (circle)
500 op/s
45 fps
60 fps
60 fps
60 fps
1000 op/s
21 fps
30 fps
32 fps
32 fps
2500 op/s
9 fps
12 fps
12 fps
12 fps
5000 op/s
4 fps
6 fps
6 fps
6 fps
10000 op/s
3 fps
4 fps
4 fps
4 fps
15000 op/s
2 fps
2 fps
3 fps
3 fps
Fill (rect)
500 op/s
60 fps
60 fps
60 fps
60 fps
1000 op/s
60 fps
60 fps
60 fps
60 fps
2500 op/s
33 fps
35 fps
60 fps
60 fps
5000 op/s
15 fps
16 fps
60 fps
60 fps
10000 op/s
6 fps
6 fps
32 fps
32 fps
15000 op/s
4 fps
4 fps
21 fps
21 fps
Sprite
500 op/s
60 fps
60 fps
60 fps
60 fps
1000 op/s
60 fps
60 fps
60 fps
60 fps
2500 op/s
60 fps
60 fps
60 fps
60 fps
5000 op/s
60 fps
60 fps
60 fps
60 fps
10000 op/s
50 fps
60 fps
60 fps
60 fps
15000 op/s
30 fps
37 fps
37 fps
60 fps
Perf Inc
Stroke (circle)
10000 op/s
n/a
25%
53%
39%
Stroke (rect)
10000 op/s
n/a
15%
75%
71%
Fill (circle)
10000 op/s
n/a
25%
25%
0%
Fill (rect)
10000 op/s
n/a
3%
81%
81%
Sprite
10000 op/s
n/a
17%
17%
0%
Sprite
15000 op/s
n/a
19%
19%
38%
obiot
August 5, 2023, 1:17am
5
(M1 Max / Chrome)
14.4.0
14.5.0
15.0.0
15.3.0
15.9.0
Stroke (circle)
500 op/s
60 fps
60 fps
60 fps
60 fps
60 fps
1000 op/s
60 fps
60 fps
60 fps
60 fps
60 fps
2500 op/s
31 fps
48 fps
60 fps
60 fps
60 fps
5000 op/s
14 fps
22 fps
32 fps
37 fps
44 fps
10000 op/s
8 fps
10 fps
16 fps
16 fps
22 fps
15000 op/s
5 fps
7 fps
10 fps
11 fps
11 fps
Stroke (rect)
500 op/s
60 fps
60 fps
60 fps
60 fps
60 fps
1000 op/s
60 fps
60 fps
60 fps
60 fps
60 fps
2500 op/s
60 fps
60 fps
60 fps
60 fps
60 fps
5000 op/s
37 fps
40 fps
60 fps
60 fps
60 fps
10000 op/s
15 fps
18 fps
60 fps
60 fps
60 fps
15000 op/s
10 fps
10 fps
60 fps
60 fps
60 fps
Fill (circle)
500 op/s
45 fps
60 fps
60 fps
60 fps
60 fps
1000 op/s
21 fps
30 fps
32 fps
32 fps
32 fps
2500 op/s
9 fps
12 fps
12 fps
12 fps
12 fps
5000 op/s
4 fps
6 fps
6 fps
6 fps
6 fps
10000 op/s
3 fps
4 fps
4 fps
4 fps
4 fps
15000 op/s
2 fps
2 fps
3 fps
3 fps
3 fps
Fill (rect)
500 op/s
60 fps
60 fps
60 fps
60 fps
60 fps
1000 op/s
60 fps
60 fps
60 fps
60 fps
60 fps
2500 op/s
33 fps
35 fps
60 fps
60 fps
60 fps
5000 op/s
15 fps
16 fps
60 fps
60 fps
60 fps
10000 op/s
6 fps
6 fps
32 fps
32 fps
32 fps
15000 op/s
4 fps
4 fps
21 fps
21 fps
21 fps
Sprite
500 op/s
60 fps
60 fps
60 fps
60 fps
60 fps
1000 op/s
60 fps
60 fps
60 fps
60 fps
60 fps
2500 op/s
60 fps
60 fps
60 fps
60 fps
60 fps
5000 op/s
60 fps
60 fps
60 fps
60 fps
60 fps
10000 op/s
50 fps
60 fps
60 fps
60 fps
60 fps
15000 op/s
30 fps
37 fps
37 fps
60 fps
60 fps
Perf Inc
14.4.0
14.5.0
15.0.0
15.3.0
15.9.0
Total
Stroke (circle)
10000 op/s
n/a
25%
53%
2%
25%
66%
Stroke (rect)
10000 op/s
n/a
15%
75%
0%
0%
75%
Fill (circle)
10000 op/s
n/a
25%
25%
0%
0%
25%
Fill (rect)
10000 op/s
n/a
3%
81%
0%
0%
81%
Sprite
10000 op/s
n/a
17%
17%
0%
0%
17%
Sprite
15000 op/s
n/a
19%
19%
38%
0%
50%
With the last 15.9 version, we conclude for now a series of update and improvements to our WebGL renderer that started with version 14.4, and aimed to improve the API and improve performances drastically. This includes :
Enable batching for all primitive drawing operations
Proper Path2D-like API implementation (mimicking the canvas native Path2D API)
Optimize access to texture and drawing operations
Faster implementation of few utility function (including color packing and friends)
Fix potential memory leak when saving/restoring the renderer context or when deleting texture
Fix how Alpha and globalAlpha values are applied (so that both Canvas and WebGL renderer behaviour match)
As you can see in the table below, we got now up to 81% performance improvements when drawing primitives, and up to 50% improvements when drawing sprites. With the latter now allowing to claim that melonJS can draw 15’000 sprites per frame at 60fps.