Skip to content
  • Overview
  • Curriculum
    • FLUMental maths and numerical fluency
    • MKTMarkets and products
    • CSData structures and algorithms
    • PYPython and data for quants
    • NUMNumerical methods
    • SYSSystems and low latency
      • 1Computer architecture

        • Architecture: caches, branch prediction and SIMD
      • 2C++ for trading

        • C++ for trading: RAII, moves and what belongs on the hot path
      • 3Concurrency

        • Concurrency: atomics, memory ordering and lock-free queues
      • 4Networking

        • Networking: multicast market data, kernel bypass and gap recovery
      • 5Measurement

        • Latency, the memory hierarchy and why the tail is the number
      • 6Order book engineering

        • Order book engineering: data structures and the operations they serve

Practise

  • Question bank
  • Mental arithmetic
  • Market simulator
  • Arbitrage trees
  • Horse racing
  • Bid book
  • Screening tests
  • Mock papers

Reference

  • Formula reference
  • Search

Your record

  • Review queue
  • Progress
  • Leaderboard
  • Profile
  • Invite friends
AccountSend feedback
  1. Curriculum
  2. /Quantitative development
  3. /Systems and low latency
  4. /C++ for trading

C++ for trading: RAII, moves and what belongs on the hot path

SYS · Chapter 2·12 min read·Asked at Hudson River Trading, Jump, Citadel Securities, Optiver

Assumes Architecture: caches, branch prediction and SIMD.

After this lesson you should be able to

  • Explain RAII and why it is the foundation of safe C++.
  • Distinguish copy from move and say when each happens.
  • List what must not appear on a latency-critical path.

C++ is used on trading paths because it gives deterministic control over memory and timing with no runtime pauses. The language features that matter are the ones supporting that: deterministic destruction, value semantics, and the ability to say exactly what happens and when.

Definition 2.1

RAII

Resource acquisition is initialisation — Tie a resource to an object’s lifetime: acquire in the constructor, release in the destructor. Because destructors run deterministically when scope is left — including when an exception unwinds — there is no way to forget the release and no garbage collector deciding when it happens. This is the single most important idea in the language, and it is why unique_ptr, lock_guard and vector all follow the same pattern.

Proposition 2.2

Copy against move

A copy duplicates the resource; a move transfers ownership and leaves the source empty. Moves happen for temporaries and for anything explicitly std::moved, and they turn an O(n)O(n)O(n) copy of a container into an O(1)O(1)O(1) pointer swap.

Holds when

  • Returning a local by value is free — the compiler elides the copy entirely.
  • std::move does not move anything; it is a cast that permits a move.
  • A moved-from object is valid but unspecified — you may destroy or assign to it, not read it.
AvoidWhyInstead
new / mallocMay lock, may fault, unbounded latencyPreallocate; use a pool
std::mapNode-based, a cache miss per levelvector or a flat map
Virtual dispatchAn indirect branch and no inliningTemplates, or a tagged union
Exceptions on the pathThe throw path is very slowReturn codes for expected failures
Logging to a fileSyscall, possible blockingLock-free queue to another thread
std::shared_ptr copiesAtomic refcount on every copyPass by reference; unique_ptr for ownership
Table 2.3 · What does not belong on the hot path. Allocation is the first thing to remove and the most important. Everything else on the list costs tens of nanoseconds; allocation can cost microseconds and its worst case is unbounded.
Predictable branch1Virtual call3Mispredicted branch15Heap allocation100System call1,000
Figure 2.4 · What does not belong on the hot path. Roughly, and the ordering is the point. A new in the middle of a tick handler costs a hundred times a branch and can block on the allocator’s lock; a syscall is another order beyond that. Hot-path code allocates nothing and calls nothing that might sleep.

Why allocation is the cardinal sin. A call to new may take a lock in the allocator, may search a free list, may request memory from the kernel, and may trigger a page fault when the memory is first touched. Each of those is rare and none is bounded, so the mean cost looks fine and the tail is terrible — which is exactly the shape of failure a trading system cannot tolerate. Preallocating converts an unbounded worst case into a known one, and that predictability is worth more than the average nanoseconds saved.

The rest of this lesson is in Premium

You have read the opening. 10 more sections follow, including 4 worked examples and 3 quick checks.

Start the free 7-day trialSign in

Nothing is charged for 7 days, and you can cancel before then. Or read Complexity: reading it off, and deriving it in full, free.

← Architecture: caches, branch prediction and SIMDConcurrency: atomics, memory ordering and lock-free queues →
On this page
  • RAII
  • Copy against move
  • What does not belong on the hot path
  • What does not belong on the hot path

QuantMax · 141 lessons · 1342 questions · c5c0caa

  • Premium
  • Arbitrage trees
  • Horse racing
  • Invite friends
  • Account
  • About QuantMax
  • Terms
  • Privacy

Firm names identify publicly reported question patterns and nothing more. QuantMax is not affiliated with, endorsed by, or recruiting for any firm named in the curriculum. Everything you do in lessons and the question bank is kept to your account.