Update: Comparing Sprite Kit Physics and Direct Box2D Simulation Times

- jnorton - Element 84

In a previous post I compared Sprite Kit physics to using Box2D directly. In that comparison I used frames per second as measured by Instruments, but it is useful to look at straight simulation time (ignoring rendering time), which I present here.

The code used to time the physics simulation in Sprite Kit is given here:

-(void)didEvaluateActions {
    physicsStartTime = [NSDate timeIntervalSinceReferenceDate];
    if (sampleStartTime == 0) {
        sampleStartTime = physicsStartTime;
    }
}

-(void)didSimulatePhysics {
    physicsEndTime = [NSDate timeIntervalSinceReferenceDate];
    frameCount++;
    
    simulationTime += (physicsEndTime - physicsStartTime);
    if (physicsEndTime - sampleStartTime > 1.0 - EPSILON) {
        NSLog(@"Average simulation time = %f", (simualtionTime / (double)frameCount));
        simulationTime = 0;
        sampleStartTime = 0;
        frameCount = 0;
    }
    
}

These are methods of SKScene and part of the Sprite Kit event loop. didEvaluateActions is called just before
and didSimulatePhysics is called just after the physics simulation. physicsStartTime, etc., are member variables on my SKScene implementation, and are intialized to zero at startup.

Again, the project used for these tests is available as a GitHub project. The tests were conducted on an iPhone 5, iOS 7.0.4. The project was built in Xcode 5 with the -Os optimization level (Fastest, Smallest). The Box2D version used for the simulations is version 2.2.1.

The only difference in these results from the previous post is that these provide physics simulation times (in milliseconds) directly instead of frames per second, which incorporates rendering time as well. The average simulation time is computed and output approximately once per second. This breaks down when the time for simulating one frame takes more than one second, but at that point the simulations are too slow to be useful in a game anyway.

The two tests shown here are the same as those shown in the previous post, namely, elastic and inelastic collisions involving small boxes. These tests were conducted using 50, 100, 150, 200, 250, 300, 350, and 400 boxes. The results are summarized in the following sections.

Test 1 – Elastic Collisions

This test involved boxes bouncing off the sides of the screen and each other. The collisions were elastic, meaning the colliding boxes don’t lose energy and thus never stop. See the previous post for screenshots and a better description.

The tow tables summarize the average simulation times for the first 16 seconds of each test run. Each row represents the samples at a given time in the test for all the test runs (50 boxes, 100 boxes, etc.).

The first table shows the results for the direct Box2D simulations.

Box2D (restitution = 1.0, friction = 0, angular damping = 0, linear damping = 0, gravity = 0)
50 Boxes 100 Boxes 150 Boxes 200 Boxes 250 Boxes 300 Boxes 350 Boxes 400 Boxes
Sample Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms)
0 1.51 3.59 5.83 9.63 20.46 44.97 289.07 447.43
1 1.11 2.67 4.22 5.02 7.11 11.0 250.47 590.1
2 1.11 2.44 4.1 4.85 7.62 9.94 87.19 452.48
3 1.08 2.51 4.11 4.66 6.5 9.06 14.83 410.12
4 1.03 2.56 3.99 4.62 6.32 8.85 15.11 397.3
5 1.04 2.46 3.94 4.65 6.47 9.09 16.52 367.85
6 1.03 2.46 4.05 4.67 6.59 9.34 15.06 349.34
7 1.04 2.47 3.96 4.61 6.53 8.75 20.53 348.67
8 1.04 2.45 3.94 4.54 6.29 8.79 27.71 339.41
9 1.06 2.44 3.95 4.59 6.39 8.88 24.03 332.53
10 1.02 2.45 3.97 4.46 6.33 8.72 32.07 341.02
11 1.01 2.45 3.96 4.48 6.24 8.88 21.02 352.85
12 1.02 2.62 3.89 4.44 6.28 8.97 20.38 320.34
13 1.06 2.43 3.89 4.49 6.31 8.74 24.34 328.89
14 1.05 2.42 3.99 4.49 6.35 8.8 20.94 318.27
15 1.0 2.46 3.92 4.58 6.43 8.84 18.54 336.07

The simulation times look very good until at least 200 boxes, and for the most part look good up until 300 boxes.

The second table represents the test runs done using Sprite Kit physics.

Sprite Kit (restitution = 1.0, friction = 0, angular damping = 0, linear damping = 0, gravity = 0)
50 Boxes 100 Boxes 150 Boxes 200 Boxes 250 Boxes 300 Boxes 350 Boxes 400 Boxes
Sample Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms)
0 3.05 5.24 10.03 18.26 66.22 227.92 363.44 602.84
1 2.22 3.94 6.57 9.32 13.78 259.07 1018.94 401.5
2 2.17 3.87 6.51 9.24 13.83 324.82 267.56 323.8
3 2.09 3.82 6.39 9.26 13.29 482.62 1600.28 4591.79
4 2.21 3.98 6.34 9.17 14.48 924.93 259.21 1029.01
5 2.12 4.0 6.37 8.24 14.71 150.15 2798.99 545.44
6 2.21 4.78 6.52 8.54 16.99 952.84 555.37 755.65
7 2.09 4.97 6.43 8.27 16.48 2221.62 867.88 688.72
8 2.19 4.95 6.42 8.28 26.19 364.39 1016.83 598.14
9 2.18 5.2 6.43 8.54 54.24 424.59 546.58 981.87
10 2.14 5.05 6.48 8.63 109.21 422.96 784.93 821.71
11 2.17 5.1 6.49 8.61 281.63 293.37 781.34 940.54
12 2.12 5.15 6.47 8.81 527.68 2449.71 893.73 633.11
13 2.12 5.14 6.5 8.9 927.89 385.01 921.82 901.76
14 2.13 5.14 6.57 9.15 116.94 334.61 324.46 717.27
15 2.17 5.41 6.5 9.31 539.98 412.18 3444.5 743.81

The first thing to notice here is that the simulation times are about twice that of the direct Box2D implementation. The Sprite Kit physics simulations also tend to get unusable around 250 boxes.

Test 2 – Inelastic Collisions

This test involves inelastic collision (collisions where colliding objects lose energy and slow down after collisions). Of particular interest here is how the various APIs handle sleeping, which is when an object has slowed down enough that it is considered at rest, and no longer needs to be simulated (until something else collides with it). This can have a big impact on performance.

Here are the simulation times for the direct Box2D implementation:

Box2D (restitution = 0.1, friction = 0.1, angular damping = 0, linear damping = 0, gravity = -1.5)
50 Boxes 100 Boxes 150 Boxes 200 Boxes 250 Boxes 300 Boxes 350 Boxes 400 Boxes
Sample Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms)
0 1.82 3.7 5.27 7.66 12.02 16.15 18.94 23.2
1 1.62 3.15 5.5 7.1 8.94 12.14 30.48 29.96
2 1.75 3.49 7.4 8.06 10.19 12.33 43.76 23.68
3 1.74 3.37 7.75 8.03 10.04 11.29 20.12 16.64
4 1.75 3.52 7.57 17.77 13.33 11.25 20.78 18.06
5 1.53 2.4 10.61 7.74 26.26 11.77 31.39 25.27
6 0.75 1.06 9.06 7.61 10.14 65.67 168.45 35.52
7 0.34 1.1 6.35 7.44 10.59 11.34 15.21 5.17
8 0.32 1.07 2.86 2.91 11.16 12.19 7.41 4.81
9 0.29 1.07 2.23 2.28 10.07 11.32 7.19 4.85
10 0.3 1.1 2.25 2.29 9.98 11.22 7.2 4.85
11 0.29 1.08 2.15 2.24 10.07 11.33 7.12 4.81
12 0.31 1.06 2.23 2.29 10.04 3.71 7.2 4.85
13 0.3 1.09 2.16 2.25 10.02 3.51 7.13 4.9
14 0.3 1.03 2.22 2.32 10.09 3.42 7.14 4.85
15 0.3 1.07 2.27 2.25 10.19 3.44 7.34 4.79

The peformance is similar to that of the previous test (elastic collisions), but we see as the simulation progresses (and the falling boxes stack up), the simulation times decrease as most of the boxes go into sleeping mode.

Here are the simulation times for Sprite Kit physics

Sprite Kit (restitution = 0.1, friction = 0.1, angular damping = 0, linear damping = 0, gravity = -1.5)
50 Boxes 100 Boxes 150 Boxes 200 Boxes 250 Boxes 300 Boxes 350 Boxes 400 Boxes
Sample Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms) Avg. Sim. Time (ms)
0 4.23 7.4 19.39 44.31 62.25 161.1 254.11 337.22
1 3.27 5.72 8.24 14.97 19.76 209.48 633.94 1082.25
2 4.4 8.18 12.33 67.62 302.7 1170.97 2063.56 202.92
3 4.89 9.29 14.68 249.22 1062.41 237.36 620.79 2090.48
4 5.01 9.67 14.75 408.64 268.71 1687.56 373.34 565.74
5 9.43 9.65 173.02 298.77 1617.6 358.74 306.87 316.2
6 3.94 9.75 20.44 140.14 221.32 191.77 2786.22 3602.25
7 4.46 9.75 14.83 151.3 750.64 996.79 421.87 490.03
8 4.47 9.71 14.84 117.96 963.63 212.24 426.74 555.7
9 4.52 9.73 14.8 134.6 965.39 520.58 428.43 571.2
10 4.47 9.75 14.85 123.63 968.13 926.11 303.45 346.69
11 4.55 9.69 14.97 209.9 966.78 249.33 2749.4 321.02
12 4.59 9.74 14.76 122.99 972.0 1197.03 543.96 2155.56
13 4.57 9.75 14.99 135.22 1004.77 220.23 420.95 404.32
14 4.47 9.7 14.78 187.51 136.14 952.87 246.43 319.09
15 4.44 9.75 15.04 110.89 329.21 837.71 2273.71 1696.03

The simulation times are already high by 150 boxes, and certainly unacceptable by 200 boxes. Again, the times are typically at least twice as long as those of the direct Box2D implementaiton. Another thing to notice is that the simulation time does not seem to benefit from sleeping boxes.

Conclusion

The data presented here makes it clearer that Sprite Kit physics does not perform as well as a direct implementation of Box2D. There may be many reasons for this (setting up collision handlers that aren’t being used, perhaps), but at face value it does not look good. Of particular concern is the seeming lack of response to sleeping objects. This coupled with the repeatabilty problems discussed in the previous post confirm my earlier conclusion that Sprite Kit physics is not quite ready for production use.