Skip to content

Performance

imshooter edited this page Oct 23, 2026 · 4 revisions

Every number on this page was measured on one computer, with the scripts in the tests folder of the repository: the queries with 3DAndreas 0.5.1, the physics with 0.6.3 and the routes with 0.7.0. The time of the component is what A3D_GetStats reports: the time spent on the thread of the server simulating and working out updates.

Against ColAndreas

The same queries on ColAndreas 1.5 and on 3DAndreas, over the whole map, measured with tests/colandreas.pwn:

ColAndreas 1.5 3DAndreas
Server ready after launch 2.8 s 0.47 s
Private memory of the server 557 MB 178 MB
10,000 rays of 100 metres 70 ms 16 ms
10,000 lines of sight 70 ms 14 ms
10,000 ground heights 73 ms 18 ms
1,000 rays that return every hit 19 ms 9 ms
1,000 contact tests 7 ms 2 ms

Time of one query against ColAndreas

A bare server, with neither of them, is ready in 0.25 s and uses 51 MB.

Queries

Query Time per call
A3D_RayCast, 100 metres 1.6 µs
A3D_IsLineOfSight, 100 metres 1.4 µs
A3D_FindGround 1.8 µs
A3D_RayCastAll 9 µs
A3D_IsModelColliding 2 µs
A3D_OverlapSphere, 5 metres 3 µs
A3D_GetPlayersInCone with sight 2.4 µs
A3D_GetWaterLevel 0.2 µs
A3D_IsPointInWater 0.6 µs
A3D_PredictTrajectory, landing 60 metres away 60 µs
A3D_RemoveBuilding 0.2 ms

Routes

Question Time per call
A3D_FindRoute across the map, with its points 30 to 50 µs
A3D_MeasureRoute across the map 10 to 20 µs
A3D_FindNearestByRoute of 50 places 0.3 ms
A3D_GetNearestPathPoint 1 to 2 µs
A3D_GetRouteProgress on a route of 400 points 1 to 5 µs
A3D_FindRoute on foot, 100 metres on the navigation mesh 10 µs
A3D_FindRoute on foot across a city, on the paths and the mesh 50 µs
A3D_GetNearestWalkPoint 1 µs
A3D_WalkRayCast, 80 metres 2 µs
A3D_GetRandomWalkPoint, 60 metres 30 µs

The contraction hierarchies take about a second to build when the server starts, on threads of their own. The routes take about 30 MB of memory, two thirds of it for walks, and the navigation mesh about 65 MB. See Routes.

Against a GPS plugin

samp-gps-plugin 1.4.1 finds paths with A* over the nodes of a file of its own, and gives the node nearest to a point. The same five routes on the same server, tests/compare.pwn:

Route Plugin, length Plugin, path Plugin, nearest node 3DAndreas, length 3DAndreas, route with its points
Grove Street to the Doherty garage 6,586 m 4.0 ms 6.4 ms 6,923 m 48 µs
The Doherty garage to Four Dragons 5,699 m 2.4 ms 6.2 ms 5,697 m 30 µs
Four Dragons to Angel Pine 7,382 m 4.6 ms 6.2 ms 7,387 m 50 µs
Angel Pine to the Market 4,571 m 0.8 ms 6.2 ms 4,571 m 30 µs
The Market to Grove Street 1,644 m 0.4 ms 6.2 ms 1,525 m 29 µs

A route with the plugin also needs the nodes nearest to both ends, so it costs between 13 and 17 ms against tens of microseconds. The lengths are those of A3D_ROUTE_SHORTEST, which weighs distance as the plugin does. The file of the plugin marks 961 of its links one way, where the game marks 11,524, so the shorter route it finds from Grove Street goes against the traffic. The route from the Market is shorter with 3DAndreas because it starts on the road beside the point rather than at the nearest node.

Physics

tests/stress.pwn runs four scenarios for a minute each. The time of the component is shown as a share of one core, 10 milliseconds a second being 1%, next to the CPU the whole server used on all its threads, bots and network included:

Scenario Component, share of one core Whole server, share of one core Updates sent
A pool table, a shot every six seconds 0.8% 2.7% 64 a second
Eight pool tables, a shot on each every six seconds 1.8% 5.6% 405 a second
Waves of 100 objects thrown every ten seconds, 50 bots connected 1.0% 4.3% 165 a second
500 boxes in an arena, 50 kicked every two seconds, 50 bots connected 3.1% 9.5% 816 a second
The 500 boxes at rest 0.06% 1.3% none

However many objects move at once, no more than 3dandreas.max_updates updates go out a second, so no client falls behind. See Configuration.

Objects at rest cost almost nothing, so the cost follows the objects in motion, not the objects created.

The same scenarios at growing counts, a minute per point:

3DAndreas main-thread time by object count

Object updates sent by object count

The 2,000 kicked boxes cost 11% of one core and stay at the limit of max_updates. Boxes at rest cost the same at 100 and at 2,000.

Slowest ticks by object count

The server runs a tick every 5 ms. One tick in a thousand took 7 ms or more in nearly every run, and the longest gaps come and go with no trend as objects grow.

Server memory by object count

Memory follows the map, not the objects: 2,000 boxes add about 11 MB to a server of 180 MB.

The numbers change by about a fifth from one session to another on the same computer, so compare runs made one after the other.

Vehicles

A thousand parked vehicles cost 4.3 ms a second, the check of their positions on every step. With 3dandreas.vehicles set to false, the same server costs 0.43 ms a second. See Configuration.

Measuring a server

A3D_GetStats gives the time of the component and the updates it sent since the start. Read it twice and divide the difference by the seconds between the reads. The time of the callbacks the component calls belongs to the scripts and shows in a Pawn profiler.

Home

Guides

Reference

Functions

Creating objects
Motion
Placement
Behaviour
Display and data
Rays
Shapes
Players, vehicles and actors
Map probes
Screen
Map objects
Water
Models and surfaces
Rotations and offsets
Vehicles
Routes
Route display
Walking
Callbacks

Clone this wiki locally