Home › Forums › Sim Racing & Driving Mechanics › Scripting Engine Overhead: C++ Native vs Lua/C# Garbage Collection Spikes: Fundamental Mechanics and Deep Mathematical Modeling
- This topic has 3 replies, 3 voices, and was last updated 3 days, 11 hours ago by
Benjamin Taylor.
-
AuthorPosts
-
October 14, 2026 at 8:50 pm #117688
Benjamin TaylorMemberI’ve been benchmarking our team’s game client and keep hitting micro-stutters during competitive matches that map almost perfectly onto GC collection cycles in our Lua scripting layer. Before we commit to a full architecture rewrite, I need real numbers from people who’ve actually lived through this in production.
🎮 Battlestation & Rig: Ryzen 7 5800X3D | RTX 3080 Ti Suprim | 32GB B-Die 3800 CL14 | Fractal Torrent | Samsung Odyssey Neo G8 32″ 4K 240Hz Mini-LED | Custom Tofu60 Lubed Gateron Oil Kings + Lamzu Maya 4K + Artisan Hien Mid | Beyerdynamic DT 990 Pro (250 Ohm) + FiiO K5 Pro ESS DAC📍 Oslo (Norway)"Rapid trigger active, zero deadzone; never miss a counter-strafe."October 15, 2026 at 2:18 am #117844
James MorganMemberThe core difference comes down to who owns the allocation and when collection happens. In C++ native you’re paying for explicit control—every allocation is either on the stack (free via a simple pointer bump on scope exit) or on the heap via operators you control, so there’s zero hidden pause cost baked into your hot loop. The “overhead” you’re measuring in Lua or C# isn’t really the allocation itself; it’s the collector’s debt collection. Lua runs an incremental mark-sweep GC where each frame only advances a fixed number of GC steps (the
GCSTEPSIZEandGCSTEPMULTconstants). Between frames it quietly works off the allocation debt, but if you allocate a burst one frame—say building a temporary vector for pathfinding—the debt carries over and suddenly a later frame pays for it in a synchronous mark phase, producing that classic 2-3ms hitch on a single core.🎮 Battlestation & Rig: i7-14700K | RTX 4070 Ti Super | 32GB DDR5 6400 CL32 | Lian Li O11 Dynamic | ASUS ROG Swift Pro PG248QP 24.1″ 540Hz Esports-TN | Fanatec Gran Turismo DD Pro (8Nm) + ClubSport V3 Load Cell Pedals | HyperX Cloud III Wireless + Dolby Atmos for Headphones📍 Singapore (Singapore)"1% low FPS flat as a runway before queuing high-elo ranked."October 18, 2026 at 5:00 pm #118818
Chloe MorganMemberThe core issue isn’t that C# or Lua are “slower” — it’s that GC-based runtimes trade predictability for convenience, and in competitive titles predictability wins every time. Native C++ has zero automatic collection, so your heap cost is entirely explicit: you pay for allocations when you make them, never during a frame you didn’t expect. The problem with C# is the generational mark-and-sweep collector, which works on the principle that most objects die young. When your live-set growth outpaces the young-gen threshold, it forces a collection cycle, and depending on the mode you’re burning cycles.
The minor GCs are usually fast but the full collection — especially the concurrent mark phase racing against your main thread — produces those micro-stalls that show up as frame-time spikes, not average?
"i7-14700K Lite Load Mode 4 (-0.080V Offset) | 253W Intel Baseline Profile"October 21, 2026 at 5:58 am #119630
Benjamin TaylorMemberFollowed the advice and turned off that fancy BIOS setting everyone mentioned (the one about the power state / C-states stuff), and honestly the framedrops are basically gone now. Was tearing my hair out for weeks with these random stutter spikes, and it turns out it was more of a system-level thing than the engine itself. Thanks guys, you’re legends — finally back to smooth 144 again. 🎮
"Dota 2 Immortal Bracket | Position 1 Carry • 7.5k MMR" -
AuthorPosts
- You must be logged in to reply to this topic.