liveBook · Manning

Performance

As explained in Modern C, Third Edition

Performance is the measurable efficiency of a program or operation, commonly including execution time and resource consumption.

Consider timing a C loop by calling timespec_get before and after it. The elapsed time is a measurement of the compiled program, not a reliable prediction from how the source code looks. A compiler may change the work performed, while the timing calls themselves add work. section 16.4

Listing 16.1 Measuring several code snippets repeatedly
    timespec_get(&t[0], TIME_UTC);
    /* Volatile for i ensures that the loop is effected */
    for (uint64_t volatile i = 0; i < iterations; ++i) {
      /* do nothing */
    }
    timespec_get(&t[1], TIME_UTC);
    /* s must be volatile to ensure that the loop is effected */
    for (uint64_t i = 0; i < iterations; ++i) {
      s = i;
    }
    timespec_get(&t[2], TIME_UTC);
    /* Opaque computation ensures that the loop is effected */
    for (uint64_t i = 1; accu0 < upper; i += 2) {
      accu0 += i;
    }
    timespec_get(&t[3], TIME_UTC);
    

The timed loops use volatile objects or an opaque computation to keep the intended work from being optimized away. Compare what each loop actually requires before comparing its times. section 16.4

Choose an algorithm before tuning its implementation. An algorithmic complexity claim calls for a proof; a claim that particular code runs faster calls for measurements. Complexity proofs are deferred here, but the distinction matters: neither a plausible argument about source code nor one fast run establishes a performance gain. section 16.4

For a defensible timing comparison:

  • Repeat measurements and report statistics rather than treating one elapsed time as decisive. section 16.4
  • Account for the measurement apparatus. A call to timespec_get takes time and can alter the compiler’s assumptions around the call. section 16.4
  • Inspect generated code when a surprising result may reflect different compiler output rather than the operation you meant to compare. section 16.4
Table 16.1 Comparison of measurements
Loop Sec per iteration Difference Gain/loss Conclusive
0 volatile loop 1.97⋅10-09
1 volatile store 3.66⋅10-10 -1.60⋅10-09 -81% Yes
2 Opaque addition 3.45⋅10-10 -2.10⋅10-11 -6% No
3 Plus timespec_get 1.77⋅10-08 1.74⋅10-08 +5043% Yes
4 Plus mean 2.62⋅10-08 8.5⋅10-09 +48% Yes
5 Plus variance 2.90⋅10-08 2.8⋅10-09 +11% Yes
6 Plus skew 3.17⋅10-08 2.7⋅10-09 +9% Yes

The comparison marks a small measured difference as inconclusive while identifying larger differences as conclusive. Its per-iteration figures belong to these particular loops and measurements, not to C loops generally. section 16.4

TAKEAWAY: Do not trade correctness or safety for speed. Premature optimization can damage readability and maintainability; unsafe access, uninitialized objects, expired lifetimes, and integer overflow can have much worse consequences. Once a real need is measured, inline functions, carefully valid restrict-qualified pointers, and function attributes may offer optimization opportunities. Any improvement claim still needs thorough measurement and statistics. section 16.0 section 16.5

How Modern C, Third Edition covers it

How deep it goes
Works through repeated loop timings, statistics, measurement bias, and generated assembly; defers proofs of algorithmic complexity.
Examples
Compares timed C loops, calls to timespec_get, statistics collection, GCC and Clang assembly, and a table of per-iteration results.
What it assumes
Assumes familiarity with C loops, functions, and compilation; introduces the need for rigorous timing while deferring complexity proofs.
What you can do after
Evaluate/understand performance claims using repeated timings, statistics, and inspection of compiled code without sacrificing correctness.
How it connects
Connects algorithmic complexity, compiler optimization, volatile, inline functions, restrict, correctness, and statistical measurement.

Also explained in

Compare how 40 books explain performance →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Modern C, Third Edition. The section links point to the parts of the book it draws on.