Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Efficiency

Avoid O(n) algorithms on hot paths (no-linear-hot-paths)

System call dispatch, scheduler enqueue, and frequent query operations must not introduce O(n) complexity where n is a quantity that can be large (number of processes, number of file descriptors, etc.). Demand sub-linear alternatives.

// Bad — O(n) scan on every enqueue
fn select_cpu(&self, cpus: &[CpuState]) -> CpuId {
    cpus.iter()
        .min_by_key(|c| c.load())
        .expect("at least one CPU")
        .id()
}

// Good — maintain a priority queue
// so selection is O(log n)
fn select_cpu(&self) -> CpuId {
    self.cpu_heap.peek().expect("at least one CPU").id()
}

See also: PR #1790.

Minimize unnecessary copies and allocations (minimize-copies)

Extra data copies — serializing to a stack buffer before writing, cloning an Arc when a & reference suffices, collecting into a Vec when an iterator would do — should be avoided.

// Bad — unnecessary Arc::clone
fn process(&self, stream: Arc<DmaStream>) {
    let s = stream.clone();
    s.sync();
}

// Good — borrow when ownership is not needed
fn process(&self, stream: &DmaStream) {
    stream.sync();
}

See also: PR #2582 and #2725.

No premature optimization without evidence (no-premature-optimization)

Performance optimizations must be justified with data. Introducing complexity to solve a non-existent problem is rejected. If you claim a change improves performance, show the numbers.