Project

SmallFunction

A header-only C++ alternative to std::function that uses fixed-size capture optimization (small-buffer optimization) to avoid heap allocation — 3–5x faster in benchmarks.

C++14CMakeGoogle Benchmark

SmallFunction is a header-only C++ library providing SmallFun — a drop-in replacement for std::function that avoids heap allocation by storing the callable object in a fixed-size buffer on the stack.

The Problem with std::function

std::function stores its captured closure on the heap, regardless of capture size. This means every construction involves a heap allocation — even for tiny lambdas:

int x = 2;
// Heap allocation happens here:
std::function<int(int)> f = [x](int i) { return i + x; };

SmallFun to the Rescue

SmallFun takes the maximum capture size as a template parameter and stores the closure inline on the stack:

#include <SmallFun.hpp>
 
int x = 2;
// No heap allocation — stored in 64 bytes on the stack:
SmallFun<int(int), 64> f = [x](int i) { return i + x; };

If you try to capture more data than the buffer size allows, you get a compile-time error rather than silent heap overflow.

Benchmarks

ImplementationTimevs std::function
Hand-crafted functor191 ns~6x faster
SmallFun<..., 32>312 ns~3.7x faster
SmallFun<..., 64>369 ns~3.1x faster
SmallFun<..., 128>346 ns~3.3x faster
std::function1141 nsbaseline

Usage

#include <SmallFun.hpp>
 
int main() {
  int multiplier = 3;
 
  // 32-byte buffer — sufficient for capturing a single int
  SmallFun<int(int), 32> triple = [multiplier](int x) {
    return x * multiplier;
  };
 
  return triple(14); // returns 42
}

Implementation

SmallFun combines three C++ patterns:

  1. Type-erasure — a virtual Concept interface and per-type Model implementation
  2. PImpl — managing the lifetime of the type-erased model
  3. Placement-new — constructing the Model directly into the stack buffer, bypassing heap allocation

The copy constructor uses a virtual copy(void*) method on the model to deep-copy into a new buffer, handling any managed resources correctly.

Installation

SmallFunction is header-only:

git clone https://github.com/LoopPerfect/smallfunction

Add the include/ directory to your compiler's include path. Requires C++14.