← Back to Docs

Operation Tiers

Different operators have different costs, and so does the operand: += and -= cost far more with a plain-number operand than between two values that already exist. Figures are for the default anti-cheat Compuon<int> on one x64 machine unless marked deferred; see the measurement note.

TierOperationsOverhead ¹Notes
0+, -, integer scalar *, <<114 ns (x += y, both values built)Cheap when both operands already exist.
0+=, -= with a plain number or a temporary6.2 µs (x += 25), 6.6 µs (x -= Compuon<int>(25))Builds and destroys a temporary value; costs more than Tier 1. Integer-scalar * and << build none.
1=, *, /, %, >>, &, |, ^, ~5.9 µs (x = v)Re-encodes the value.
2==, !=, <, >, <=, >=not timed; a cache read took 0.2 nsReads the cached value of each side.

Tier 0: 114 ns between built values

Addition, subtraction, integer-scalar multiplication and left shift update the protected value in place. Between two values that already exist, x += y took 114 ns, cheap enough for per-frame game logic. With a plain-number operand, += and -= first build a temporary protected value and destroy it afterwards: x += 25 took 6.2 µs and x -= Compuon<int>(25) 6.6 µs, more than a Tier 1 assignment. Integer-scalar *= and <<= take the plain number directly and build no temporary (not timed). In a per-frame path, build a fixed operand once and reuse it.¹

Compuon<int> hp(100);
Compuon<int> regen(5);   // built once, reused every tick
Compuon<int> x(4);

hp += regen;             // both values built: 114 ns (x += y)
hp += Compuon<int>(10);  // temporary value per call: ~6.6 µs (x -= Compuon<int>(25))
hp -= 25;                // plain number, same: ~6.2 µs (x += 25)
x <<= 3;                 // Tier 0, not timed

Tier 1: 5.9 µs

Operations that re-encode the value from scratch. Assigning a plain number (x = v) took 5.9 µs; the other Tier 1 operators were not timed. Still usable per frame — 100 assignments come to about 0.59 ms, 3.5% of a 16.67 ms (60 Hz) frame.¹

Compuon<int> hp(100);
Compuon<int> other(2);
Compuon<int> mask(0x3F);

hp = 50;                  // assignment: 5.9 µs (x = v)
hp *= other;              // multiply: Tier 1, not timed
hp /= other;              // division: Tier 1, not timed
hp %= Compuon<int>(10);   // modulo: Tier 1, not timed (plus a temporary value)
hp >>= 1;                 // right shift: Tier 1, not timed
hp &= mask;               // bitwise AND/OR/XOR: Tier 1, not timed
auto flipped = ~mask;     // bitwise NOT (integer only): Tier 1, not timed

Tier 2: comparisons

Comparisons read the cached value of each side. They were not timed separately; a read of the cache took 0.2 ns, at the benchmark's resolution. Compare against a value that already exists or against a plain number: hp > Compuon<int>(0) first builds and destroys a temporary protected value, which took 6.1 µs on its own.¹

Compuon<int> hp(100);
Compuon<int> other(100);

bool dead  = hp <= 0;               // reads the cache
bool same  = hp == other;           // reads both caches
bool alive = hp > Compuon<int>(0);  // builds a temporary value first

Deferred mode

Compuon<T, true>keeps no plaintext, so every read and every operation folds against the server's operand bundle, and a read then decodes. On the same machine a read (val()) took 37.1 µs, about 17 times verify() (2.2 µs); x += y took 30.7 µs, x += 25 75.9 µs and x = v 43.2 µs. A comparison reads each deferred side. Use deferred mode for values read occasionally, not every frame.¹

Performance Guidelines

+In hot paths (damage calc, movement), use Tier 0 ops between values that already exist: 114 ns for x += y. Build fixed operands once; += or -= with a plain-number operand costs 6.2–6.6 µs per call.
+Tier 1 ops are fine for per-frame use. Avoid in tight inner loops (thousands of iterations).
+Comparisons against a built value or a plain number only read the cache — use them anywhere on anti-cheat values.
+100 Tier-0 adds per 60 Hz frame come to 0.07% of the frame with operands built once, 3.7% with plain-number operands.¹

¹ Measurement provenance: Compuon's internal operator benchmark (not yet in a released core), which times the operators as written on Compuon<int> and Compuon<int, true>, built with MSVC 19.51 x64 Release (/O2, LTCG link) against the Compuon core 0752031 library and run on one AMD Ryzen 7 5825U on 2026-09-28, with background load of about one core. Each figure is the median of three invocations of 9 runs. Min–max over the 27 runs: x += y 107–215 ns; x += 25 6,017–9,150 ns; x -= Compuon<int>(25) 6,327–9,276 ns; x = v 5,678–8,630 ns; cache read 0.2–0.5 ns; building and destroying a value 5,906–8,976 ns; verify() 2,098–3,964 ns; deferred val() 36,088–50,888 ns, x += y 29,813–42,663 ns, x += 25 73,575–105,403 ns, x = v 41,759–61,961 ns. Only the forms named were timed, and only on this CPU and compiler. They come from one build of the library, generated from one seed. Every SDK build comes from its own seed and times differently: on the same machine, builds from two other seeds took 113 ns and 366 ns for x += y, their other anti-cheat figures stayed within 14% of these, and their deferred figures were 0.6–1.1 times these. A re-run of the original build later the same day gave medians within 5% of these. Per-frame shares are the per-call median times 100, not a timed loop. An earlier revision of this page gave 340 ns for every Tier 0 op and 6.5 µs for Tier 1, from a single 2026-04-20 run on the same CPU model; the 340 ns was an add between two existing values, and that run put a compare at about 0.5 ns. Your numbers will differ with seed, CPU, compiler, and build flags — measure in your own build before committing to a budget.