---
description: C++ Performance
alwaysApply: false
---

# C++ Performance

Measure first. Understand the hardware. Zero-cost abstractions are the goal.

## Profile Before Optimizing

```bash
perf record -g ./myapp && perf report  # Linux CPU profiling
valgrind --tool=callgrind ./myapp      # Instruction-level
```

Tools: perf, Valgrind/Callgrind, Google Benchmark, Compiler Explorer, heaptrack, Tracy

## Cache-Friendly Data Structures

```cpp
// SoA — excellent cache utilization for field-wise iteration
struct Particles {
    std::vector<float> x, y, z;
    std::vector<float> mass;
};
// vs AoS where iterating mass loads x,y,z too. Profile first — SoA matters for hot loops.
```

## Allocation Avoidance

- **`reserve()`** — pre-allocate containers: `vec.reserve(expected_count);`
- **Stack allocation** — `std::array<char, 256>` over `std::vector` for small buffers
- **Object pools** — for frequent alloc/dealloc of same type
- **SBO** — `std::string` and `std::function` already use small buffer optimization

## Move Semantics

```cpp
// Sink parameters: take by value and move
explicit Widget(std::string name) : name_{std::move(name)} {}

// Emplace constructs in-place (avoids temporary)
items.emplace_back(arg1, arg2);
```

## constexpr Computation

```cpp
constexpr auto factorial(int n) -> int {
    int r = 1; for (int i = 2; i <= n; ++i) r *= i; return r;
}
static_assert(factorial(5) == 120); // Computed at compile time
```

## String Performance

- `std::string_view` for zero-copy read-only operations
- `reserve()` + `append()` over concatenation in loops
- `std::format` / `fmt::format` over stringstream

## Compiler Optimization

```cmake
target_compile_options(${PROJECT_NAME} PRIVATE
    $<$<CONFIG:Release>:-O3 -DNDEBUG -march=native>)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON) # LTO
```

## Anti-Patterns

- **Optimizing without profiling** — prove the bottleneck first
- **Virtual calls in hot loops** — consider CRTP, `std::variant`, or batching
- **`std::shared_ptr` in hot paths** — atomic refcount is expensive; use `unique_ptr`
