Benchmarks

This section reports the runtime overhead of the Boost.SafeNumbers types relative to the equivalent built-in types, and shows how to run the benchmarks yourself.

Each table compares three contenders at a fixed width:

  • the built-in C++ type, which is the baseline (std::uint32_t, int128_t, double, and so on),

  • Boost.SafeNumbers (boost::sn::u32, boost::sn::i128, boost::sn::f64, and so on), and

  • Boost.SafeNumerics (safe<uint32_t> and similar) for the integer benchmarks.

Each cell reports the time per element in nanoseconds (ns/op), taken as the median across repetitions. The Ratio column is how many times longer the wrapper takes than the built-in type of the same width: 1.00 means parity with the built-in type, and a larger value means the wrapper is slower. Because the baseline differs by width, every table states the type it is measured against.

Boost.SafeNumerics has no floating-point type and no 128-bit type, so the floating-point and 128-bit tables list only the built-in type and Boost.SafeNumbers. See Comparisons to Other Libraries and Languages for the details of that limitation.

How to run the Benchmarks

The benchmarks live in test/benchmarks/ and are built with Google Benchmark. They are not part of the default build: configure with -DBOOST_SAFE_NUMBERS_BUILD_BENCHMARKS=ON, which pulls Google Benchmark in with CMake FetchContent so no system install is required.

From a Boost tree that has the dependencies in place:

cmake -S . -B __build__ -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF \
  -DBOOST_INCLUDE_LIBRARIES="safe_numbers;safe_numerics;random" \
  -DBOOST_SAFE_NUMBERS_BUILD_BENCHMARKS=ON
cmake --build __build__ --config Release \
  --target benchmark_unsigned_operations benchmark_signed_operations benchmark_float_operations
./__build__/libs/safe_numbers/test/benchmarks/benchmark_unsigned_operations --benchmark_repetitions=5

The benchmarks.yml GitHub Actions workflow runs the same build across a spread of native runners, emits each suite’s JSON, and renders the per-platform sections below with test/benchmarks/render_results.py.

Methodology

Each benchmark fills a vector of 1,000,000 random values once, outside the timed region, and then for every operation evaluates op(vec[i], vec[i + 1]) across the whole vector. Each element’s result is passed through benchmark::DoNotOptimize, so the work cannot be elided, while the code is compiled at -O2 with inlining intact. That distinction matters: compiling the loop without optimization would turn the wrapper’s inline operators into real function calls and grossly overstate their cost, so the benchmarks deliberately measure optimized code. Google Benchmark picks the iteration count automatically and repeats the timing; the reported figure is the median time per element.

The integer benchmarks draw values uniformly from [1, width_in_bits - 1] and sort them in descending order. Keeping the operands small and ordered means addition, subtraction, multiplication, division, and modulo all stay on the non-overflow, non-throwing path, so the measurement reflects the cost of the safety checks rather than the cost of throwing. The floating-point benchmarks draw values uniformly from [1, 100] and measure addition, subtraction, multiplication, and division.

The numbers come from shared CI runners and reflect a single run each, so treat small differences as noise. The repetition count and median reporting keep the central figure stable, but they cannot remove the variance inherent to a shared virtual machine.

Device Benchmarks (CUDA and SYCL)

All of the safe types run inside CUDA and SYCL kernels (see CUDA Support and SYCL Support), and two dedicated benchmarks measure what the safety checks cost on the device itself:

  • test/benchmarks/benchmark_cuda_operations.cu, timed with CUDA events

  • test/benchmarks/benchmark_sycl_operations.cpp, timed with SYCL event profiling

Each compares every safe type against its own basis type running the identical kernel (boost::sn::u32 against std::uint32_t, boost::sn::u128 against the emulated 128-bit basis type, and so on), so the ratio isolates the cost of the safety checks. As in the host benchmarks, the inputs are chosen so that no check ever fires: the timed regions never enter the error reporting path, and a device_error_context covering the whole run aborts the benchmark if a check does fire.

Device Methodology

Two kernel shapes are measured for every type:

Streaming

out[i] = a[i] op b[i], one checked operation per element over 4,194,304 elements. This is the shape real element-wise kernels have. On a discrete GPU it is bound by memory bandwidth, so it shows the overhead a typical kernel actually experiences. Integer operands are drawn from [1, width_in_bits - 1] with a >= b, and floating point operands from [1, 100], mirroring the host benchmarks.

Compute-bound chain

65,536 threads each evolve one value through a serial dependency chain held in registers (256 cycles of eight to nine checked operations), so the arithmetic cannot hide behind memory traffic and the worst case per-operation cost becomes visible.

The integer chain is a fixed mixed sequence (two modulo, two addition, two division, one subtraction, and one multiplication per cycle) rather than a single repeated operation. That is deliberate: wrapping integer arithmetic is associative, so the optimizer can legally collapse a run of additions or multiplications by loop-invariant operands for the builtin baseline, and the comparison would then measure an optimizer artifact instead of the checks. Division and modulo cannot be reassociated, and interleaving them forces every step to execute for both contenders. The floating point chains are per operation (eight operations plus one restore step of the inverse kind), because IEEE arithmetic is not associative and cannot be folded.

Every family also measures the non-throwing forms against the same raw baseline: a sat_add streaming row (saturating_add), mixed (sat) and mixed (ovf) integer chains built from the saturating_* and overflowing_* functions, and (ovf) float chains built from the deferred float family with the flags accumulated and folded into the result. These rows show what checked arithmetic costs when the error report is deferred to a boundary instead of raised per operation.

Every timed region is verified afterwards: the safe results must match the builtin results bit for bit across all elements, a slice is recomputed on the host, and the process exit code reflects any mismatch. Both benchmarks accept optional positional arguments [stream_elements] [chain_cycles] [launches] [chain_threads] for scaling the run to slower or faster devices.

How to Run the Device Benchmarks

CUDA (requires the CUDA toolkit):

cmake -S . -B __build__ -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF \
  -DBOOST_INCLUDE_LIBRARIES="safe_numbers" \
  -DBOOST_SAFE_NUMBERS_BUILD_BENCHMARKS=ON \
  -DBOOST_SAFE_NUMBERS_ENABLE_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=native
cmake --build __build__ --target benchmark_cuda_operations
./__build__/stage/bin/benchmark_cuda_operations

SYCL (requires oneAPI):

cmake -S . -B __build__ -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF \
  -DCMAKE_CXX_COMPILER=icpx \
  -DBOOST_INCLUDE_LIBRARIES="safe_numbers" \
  -DBOOST_SAFE_NUMBERS_BUILD_BENCHMARKS=ON \
  -DBOOST_SAFE_NUMBERS_ENABLE_SYCL=ON
cmake --build __build__ --target benchmark_sycl_operations
./__build__/stage/bin/benchmark_sycl_operations
icpx compiles with -ffp-model=fast by default, which grants the optimizer floating point associativity; the builtin baseline chains then fold algebraically and the float comparison becomes meaningless. The build therefore pins -ffp-model=precise for the SYCL benchmark, so both contenders run IEEE arithmetic exactly as they do under nvcc. The build also splits the device code per kernel (-fsycl-device-code-split=per_kernel) because at -O3 the monolithic device image of a few hundred kernels fails to JIT on the OpenCL CPU backend.

CUDA Results: NVIDIA RTX 3060

Run on an NVIDIA GeForce RTX 3060 (sm_86, 28 SMs) with CUDA 13.1 on Ubuntu 24.04, compiled at -O2 with --expt-relaxed-constexpr, using the default sizes.

Table 1. Streaming, ratio of safe time to basis type time (RTX 3060)
Type Addition Subtraction Multiplication Division Modulo Saturating addition

u8

1.05

1.04

1.05

1.03

1.02

1.02

u16

1.00

1.00

1.00

1.00

1.00

0.99

u32

1.00

1.00

1.00

1.00

1.00

1.00

u64

1.00

1.00

1.00

1.00

1.00

1.00

u128

1.00

1.00

6.77

1.00

1.00

1.00

i8

1.23

1.22

1.22

1.16

1.15

1.04

i16

1.05

1.05

1.04

1.04

1.03

1.00

i32

1.00

1.00

1.00

1.00

1.00

1.00

i64

1.00

1.00

1.00

1.00

1.00

1.00

i128

1.00

1.00

6.79

1.00

1.00

1.00

f32

1.00

1.00

1.00

1.00

n/a

n/a

f64

1.00

1.00

1.00

1.44

n/a

n/a

In the streaming regime the checks are essentially free: the kernels are limited by memory bandwidth and the check instructions execute in the shadow of the loads. The only rows above parity are the 8-bit types (up to 1.23x, since a byte of traffic buys less time to hide the check), f64 division (1.44x), and 128-bit multiplication (about 6.8x). The multiplication overflow check on the 128-bit types is the one genuinely expensive check in the library, since it must be computed from 64-bit limbs.

Table 2. Compute-bound integer chain (RTX 3060): throwing operators and non-throwing forms against the raw chain
Type Basis type (ns/op) Throwing (ns/op) Ratio Saturating (ns/op) Ratio Overflowing (ns/op) Ratio

u8

0.0030

0.0039

1.30

0.0037

1.24

0.0036

1.21

u16

0.0030

0.0039

1.30

0.0037

1.23

0.0037

1.23

u32

0.0012

0.0034

2.82

0.0030

2.55

0.0030

2.50

u64

0.0031

0.0045

1.46

0.0044

1.44

0.0043

1.38

u128

0.0094

0.0964

10.30

0.0884

9.43

0.0925

10.28

i8

0.0020

0.0054

2.68

0.0056

2.78

0.0052

2.61

i16

0.0020

0.0058

2.93

0.0058

2.96

0.0055

2.80

i32

0.0018

0.0051

2.85

0.0052

2.92

0.0051

2.83

i64

0.0031

0.0068

2.22

0.0071

2.31

0.0067

2.19

i128

0.0121

0.0940

7.78

0.0921

7.62

0.0919

7.92

Table 3. Compute-bound floating point chains (RTX 3060): throwing operators and the deferred (overflowing) family
Type Operation Basis type (ns/op) Throwing (ns/op) Ratio Overflowing (ns/op) Ratio

f32

Addition

0.0002

0.0037

18.31

0.0011

5.39

f32

Subtraction

0.0002

0.0037

17.66

0.0011

5.37

f32

Multiplication

0.0004

0.0039

8.71

0.0012

2.69

f32

Division

0.0026

0.0057

2.22

0.0027

1.05

f64

Addition

0.0124

0.0495

4.00

0.0501

4.21

f64

Subtraction

0.0124

0.0495

4.01

0.0501

4.21

f64

Multiplication

0.0209

0.0579

2.77

0.0593

2.94

f64

Division

0.0779

0.1157

1.49

0.1196

1.55

With the arithmetic pinned in registers the checked integer types cost 1.3x to 2.9x through 64 bits, and the 128-bit chains are dominated by the multiplication check (7.8x to 10.3x). For the floating point chains the baseline operation is a single hardware instruction, so the fixed cost of the checks multiplies it: up to 18.3x for f32, and 1.5x to 4.0x for f64, whose baseline instruction is already slow on a consumer GPU. On a GPU the non-throwing integer forms buy little, because the throwing operators already compile to a well predicted branch; the deferred float family is the exception, cutting the f32 chains from 18.3x to 5.4x and f32 division to parity by dropping the per-operation classification. Real kernels sit between the two regimes, and usually much closer to the streaming one.

SYCL Results: Intel OpenCL CPU Device

Run on the OpenCL CPU device of an Intel Core i9-11900K (8 cores) with oneAPI icpx 2026.0 at -O3, -ffp-model=precise, and per kernel device code split, using the default sizes. A CPU device executes a kernel by vectorizing it across work items, and that shapes these results: a branch-free kernel body runs 8 or 16 lanes wide, and the branches of the safety checks inhibit exactly that transformation.

Table 4. Streaming, ratio of safe time to basis type time (SYCL CPU device)
Type Addition Subtraction Multiplication Division Modulo Saturating addition

u8

5.47

6.02

11.60

1.01

1.01

0.97

u16

1.03

1.06

1.87

1.15

1.25

1.02

u32

1.03

1.04

1.04

1.02

1.00

1.00

u64

1.03

1.03

1.04

1.00

1.00

1.00

u128

1.00

1.01

1.05

1.01

0.99

0.99

i8

9.69

10.84

11.32

1.14

1.14

1.52

i16

1.50

1.50

1.44

1.59

1.59

1.07

i32

1.00

1.00

1.00

0.98

0.99

0.96

i64

1.04

1.04

1.03

1.01

1.01

1.00

i128

1.01

1.01

1.11

1.01

1.00

0.99

f32

1.32

1.35

1.35

1.74

n/a

n/a

f64

1.05

1.05

1.05

1.12

n/a

n/a

For 32 bits and up the streaming results match the CUDA picture: the arrays no longer fit in cache, the kernels are bound by memory, and the checks cost 0 to 7 percent. The 8-bit rows stand out (up to 11.6x) because four million 1-byte elements fit inside the processor’s cache: those kernels are compute bound, so they measure the vectorization gap rather than memory bandwidth. The saturating addition column shows the escape hatch: saturating_add compiles to the native saturating vector instructions, so even the 8-bit rows return to parity.

Table 5. Compute-bound integer chain (SYCL CPU device): throwing operators and non-throwing forms against the raw chain
Type Basis type (ns/op) Throwing (ns/op) Ratio Saturating (ns/op) Ratio Overflowing (ns/op) Ratio

u8

0.0803

0.1198

1.49

0.1185

1.51

0.1149

1.43

u16

0.0833

0.1567

1.88

0.1224

1.46

0.1434

1.72

u32

0.0220

0.0941

4.27

0.0742

3.34

0.0697

3.16

u64

0.1259

0.1317

1.05

0.1248

0.99

0.1271

1.00

u128

0.3259

0.5082

1.56

0.4989

1.55

0.5189

1.59

i8

0.1307

0.2153

1.65

0.1344

1.06

0.1459

1.11

i16

0.0233

0.2057

8.82

0.1346

5.76

0.1406

5.90

i32

0.0215

0.2025

9.42

0.1332

6.05

0.1415

6.46

i64

0.1270

0.1858

1.46

0.1473

1.16

0.1485

1.17

i128

0.4167

0.6075

1.46

0.8602

2.06

0.9172

2.22

Table 6. Compute-bound floating point chains (SYCL CPU device): throwing operators and the deferred (overflowing) family
Type Operation Basis type (ns/op) Throwing (ns/op) Ratio Overflowing (ns/op) Ratio

f32

Addition

0.0035

0.6126

173.03

0.0060

1.68

f32

Subtraction

0.0035

0.6066

171.30

0.0072

2.11

f32

Multiplication

0.0049

0.6275

127.59

0.0071

1.43

f32

Division

0.0150

0.7521

50.01

0.0163

1.13

f64

Addition

0.0036

0.6457

179.70

0.0098

2.73

f64

Subtraction

0.0036

0.8446

234.65

0.0108

2.85

f64

Multiplication

0.0064

0.6579

102.24

0.0135

2.05

f64

Division

0.0450

0.7644

17.00

0.0475

1.05

In the chains the dominant cost on a CPU device is lost vectorization rather than the check instructions themselves. Where the baseline cannot vectorize either (the 64-bit and 128-bit chains, and the 8-bit chains whose narrow division defeats the vectorizer), the throwing types cost 1.0x to 1.9x, in line with the host benchmarks. Where the baseline vectorizes and the throwing chain does not (i16, i32, and every floating point chain), the gap is the SIMD width times the check cost, up to roughly 235x for the f64 chains.

The deferred family recovers that gap almost entirely for floats: the branch-free overflowing_* operations vectorize with the baseline, so the same chains land at 1.1x to 2.9x, two orders of magnitude better than the throwing operators, while still detecting every error at the boundary (see Overflowing Arithmetic and the deferred_errors accumulator in SYCL Support). The integer saturating_* and overflowing_* chains improve i16/i32 from about 9x to about 6x; the remaining gap is the divide by zero check that division and modulo still raise eagerly, which keeps a reporting branch in the kernel body.

The device numbers come from one machine and a single run each, so treat small differences as noise. On a discrete GPU a SYCL build should behave like the CUDA column; this machine only exposes the CPU device.

Linux x64

Run on the GitHub Actions ubuntu-latest runner using GCC 14 in release mode (-O2, C++20).

Floating-Point

Table 7. 32-bit floating point (ratio relative to float)
Operation float (ns/op) boost::sn::f32 (ns/op) Ratio

Addition

0.94

1.14

1.21

Subtraction

0.94

1.14

1.22

Multiplication

0.94

1.11

1.18

Division

0.94

1.22

1.29

Table 8. 64-bit floating point (ratio relative to double)
Operation double (ns/op) boost::sn::f64 (ns/op) Ratio

Addition

0.94

1.12

1.19

Subtraction

0.94

1.13

1.20

Multiplication

0.94

1.11

1.18

Division

1.41

1.42

1.00

Signed Integers

Table 9. 8-bit signed (ratio relative to std::int8_t)
Operation std::int8_t (ns/op) boost::sn::i8 (ns/op) Ratio safe<int8_t> (ns/op) Ratio

Addition

0.54

0.62

1.16

0.67

1.25

Subtraction

0.53

0.62

1.18

0.67

1.26

Multiplication

0.62

0.62

1.00

0.69

1.10

Division

1.87

1.87

1.00

1.87

1.00

Modulo

1.87

1.87

1.00

1.87

1.00

Table 10. 16-bit signed (ratio relative to std::int16_t)
Operation std::int16_t (ns/op) boost::sn::i16 (ns/op) Ratio safe<int16_t> (ns/op) Ratio

Addition

0.50

0.62

1.25

0.69

1.37

Subtraction

0.50

0.63

1.25

0.68

1.37

Multiplication

0.76

0.72

0.94

0.72

0.94

Division

1.87

1.87

1.00

1.87

1.00

Modulo

1.87

1.87

1.00

1.87

1.00

Table 11. 32-bit signed (ratio relative to std::int32_t)
Operation std::int32_t (ns/op) boost::sn::i32 (ns/op) Ratio safe<int32_t> (ns/op) Ratio

Addition

0.50

0.63

1.24

0.64

1.26

Subtraction

0.50

0.63

1.25

0.68

1.35

Multiplication

0.59

0.64

1.08

0.93

1.58

Division

1.87

1.87

1.00

1.87

1.00

Modulo

1.87

1.87

1.00

1.87

1.00

Table 12. 64-bit signed (ratio relative to std::int64_t)
Operation std::int64_t (ns/op) boost::sn::i64 (ns/op) Ratio safe<int64_t> (ns/op) Ratio

Addition

0.51

0.63

1.23

0.70

1.38

Subtraction

0.51

0.63

1.24

0.67

1.32

Multiplication

0.59

0.69

1.16

2.81

4.72

Division

2.18

2.18

1.00

2.18

1.00

Modulo

2.19

2.19

1.00

2.18

1.00

Table 13. 128-bit signed (ratio relative to int128_t)
Operation int128_t (ns/op) boost::sn::i128 (ns/op) Ratio

Addition

2.20

2.11

0.96

Subtraction

1.88

2.05

1.10

Multiplication

2.90

3.13

1.08

Division

5.63

6.26

1.11

Modulo

6.56

7.19

1.10

Unsigned Integers

Table 14. 8-bit unsigned (ratio relative to std::uint8_t)
Operation std::uint8_t (ns/op) boost::sn::u8 (ns/op) Ratio safe<uint8_t> (ns/op) Ratio

Addition

0.54

0.65

1.21

0.73

1.36

Subtraction

0.63

0.62

1.00

0.62

1.00

Multiplication

0.43

0.72

1.66

0.68

1.58

Division

1.25

1.25

1.00

1.87

1.50

Modulo

1.25

1.25

1.00

1.87

1.50

Table 15. 16-bit unsigned (ratio relative to std::uint16_t)
Operation std::uint16_t (ns/op) boost::sn::u16 (ns/op) Ratio safe<uint16_t> (ns/op) Ratio

Addition

0.50

0.62

1.25

0.67

1.33

Subtraction

0.50

0.62

1.25

0.63

1.25

Multiplication

0.59

0.94

1.59

0.94

1.59

Division

1.25

1.25

1.00

1.87

1.50

Modulo

1.25

1.25

1.00

1.87

1.50

Table 16. 32-bit unsigned (ratio relative to std::uint32_t)
Operation std::uint32_t (ns/op) boost::sn::u32 (ns/op) Ratio safe<uint32_t> (ns/op) Ratio

Addition

0.51

0.62

1.24

0.63

1.24

Subtraction

0.50

0.63

1.24

0.63

1.24

Multiplication

0.59

0.94

1.58

0.64

1.07

Division

1.87

1.87

1.00

1.87

1.00

Modulo

1.87

1.87

1.00

1.87

1.00

Table 17. 64-bit unsigned (ratio relative to std::uint64_t)
Operation std::uint64_t (ns/op) boost::sn::u64 (ns/op) Ratio safe<uint64_t> (ns/op) Ratio

Addition

0.51

0.63

1.23

0.63

1.23

Subtraction

0.51

0.63

1.23

0.63

1.23

Multiplication

0.60

0.94

1.58

0.82

1.37

Division

2.18

2.18

1.00

2.18

1.00

Modulo

2.18

2.18

1.00

2.18

1.00

Table 18. 128-bit unsigned (ratio relative to uint128_t)
Operation uint128_t (ns/op) boost::sn::u128 (ns/op) Ratio

Addition

1.93

2.70

1.40

Subtraction

1.89

3.42

1.81

Multiplication

2.83

2.32

0.82

Division

4.08

3.76

0.92

Modulo

4.15

4.09

0.99

Linux x86 (32-bit)

Run on the GitHub Actions ubuntu-latest runner using GCC 14 targeting 32-bit x86 (-m32) in release mode (-O2, C++20).

Floating-Point

Table 19. 32-bit floating point (ratio relative to float)
Operation float (ns/op) boost::sn::f32 (ns/op) Ratio

Addition

2.09

2.19

1.05

Subtraction

2.08

2.19

1.06

Multiplication

2.08

2.19

1.06

Division

1.89

2.53

1.34

Table 20. 64-bit floating point (ratio relative to double)
Operation double (ns/op) boost::sn::f64 (ns/op) Ratio

Addition

6.31

6.38

1.01

Subtraction

6.31

6.38

1.01

Multiplication

6.31

6.38

1.01

Division

6.32

6.21

0.98

Signed Integers

Table 21. 8-bit signed (ratio relative to std::int8_t)
Operation std::int8_t (ns/op) boost::sn::i8 (ns/op) Ratio safe<int8_t> (ns/op) Ratio

Addition

0.62

1.90

3.04

0.67

1.07

Subtraction

0.52

1.90

3.62

0.67

1.27

Multiplication

0.62

1.93

3.09

0.69

1.10

Division

1.87

1.87

1.00

1.87

1.00

Modulo

1.87

1.87

1.00

1.87

1.00

Table 22. 16-bit signed (ratio relative to std::int16_t)
Operation std::int16_t (ns/op) boost::sn::i16 (ns/op) Ratio safe<int16_t> (ns/op) Ratio

Addition

0.63

0.76

1.20

0.77

1.22

Subtraction

0.63

1.90

3.02

0.67

1.06

Multiplication

0.63

1.96

3.13

0.88

1.41

Division

1.87

1.90

1.02

1.87

1.00

Modulo

1.87

1.88

1.00

1.87

1.00

Table 23. 32-bit signed (ratio relative to std::int32_t)
Operation std::int32_t (ns/op) boost::sn::i32 (ns/op) Ratio safe<int32_t> (ns/op) Ratio

Addition

0.52

0.75

1.43

0.66

1.25

Subtraction

0.64

0.91

1.42

0.65

1.02

Multiplication

0.63

0.74

1.18

1.29

2.06

Division

1.87

1.87

1.00

1.87

1.00

Modulo

1.87

1.87

1.00

1.87

1.00

Table 24. 64-bit signed (ratio relative to std::int64_t)
Operation std::int64_t (ns/op) boost::sn::i64 (ns/op) Ratio safe<int64_t> (ns/op) Ratio

Addition

1.81

1.79

0.99

3.22

1.78

Subtraction

1.81

2.72

1.51

3.23

1.79

Multiplication

2.20

3.69

1.67

7.19

3.26

Division

4.78

5.89

1.23

5.68

1.19

Modulo

5.03

6.25

1.24

5.21

1.04

Table 25. 128-bit signed (ratio relative to int128_t)
Operation int128_t (ns/op) boost::sn::i128 (ns/op) Ratio

Addition

6.33

7.77

1.23

Subtraction

6.92

7.58

1.10

Multiplication

13.80

37.51

2.72

Division

12.30

13.57

1.10

Modulo

13.47

16.47

1.22

Unsigned Integers

Table 26. 8-bit unsigned (ratio relative to std::uint8_t)
Operation std::uint8_t (ns/op) boost::sn::u8 (ns/op) Ratio safe<uint8_t> (ns/op) Ratio

Addition

0.63

0.63

0.99

1.88

2.97

Subtraction

0.53

0.63

1.19

0.63

1.19

Multiplication

0.43

0.64

1.48

0.63

1.46

Division

1.25

1.25

1.00

1.87

1.50

Modulo

1.25

1.25

1.00

1.87

1.50

Table 27. 16-bit unsigned (ratio relative to std::uint16_t)
Operation std::uint16_t (ns/op) boost::sn::u16 (ns/op) Ratio safe<uint16_t> (ns/op) Ratio

Addition

0.63

0.64

1.01

1.89

2.99

Subtraction

0.63

0.73

1.16

0.57

0.91

Multiplication

0.44

1.89

4.32

1.99

4.56

Division

1.97

1.93

0.98

1.87

0.95

Modulo

1.89

1.92

1.01

1.87

0.99

Table 28. 32-bit unsigned (ratio relative to std::uint32_t)
Operation std::uint32_t (ns/op) boost::sn::u32 (ns/op) Ratio safe<uint32_t> (ns/op) Ratio

Addition

0.52

0.63

1.20

0.58

1.11

Subtraction

0.63

0.73

1.15

0.76

1.20

Multiplication

0.63

0.94

1.50

0.77

1.23

Division

1.87

1.87

1.00

1.87

1.00

Modulo

1.87

1.87

1.00

1.87

1.00

Table 29. 64-bit unsigned (ratio relative to std::uint64_t)
Operation std::uint64_t (ns/op) boost::sn::u64 (ns/op) Ratio safe<uint64_t> (ns/op) Ratio

Addition

1.81

1.81

1.00

1.81

1.00

Subtraction

1.81

2.20

1.22

1.93

1.07

Multiplication

2.21

2.69

1.21

2.15

0.97

Division

4.38

4.61

1.05

4.53

1.03

Modulo

4.19

4.50

1.07

4.45

1.06

Table 30. 128-bit unsigned (ratio relative to uint128_t)
Operation uint128_t (ns/op) boost::sn::u128 (ns/op) Ratio

Addition

5.88

7.31

1.24

Subtraction

6.55

7.75

1.18

Multiplication

10.40

36.02

3.46

Division

15.65

21.62

1.38

Modulo

17.33

24.33

1.40

Linux ARM64

Run on the GitHub Actions ubuntu-24.04-arm runner using GCC 14 in release mode (-O2, C++20).

Floating-Point

Table 31. 32-bit floating point (ratio relative to float)
Operation float (ns/op) boost::sn::f32 (ns/op) Ratio

Addition

0.71

1.03

1.45

Subtraction

0.71

1.03

1.45

Multiplication

0.79

1.18

1.49

Division

0.73

1.37

1.88

Table 32. 64-bit floating point (ratio relative to double)
Operation double (ns/op) boost::sn::f64 (ns/op) Ratio

Addition

0.71

1.04

1.46

Subtraction

0.71

1.04

1.46

Multiplication

0.79

1.18

1.49

Division

1.48

1.75

1.19

Signed Integers

Table 33. 8-bit signed (ratio relative to std::int8_t)
Operation std::int8_t (ns/op) boost::sn::i8 (ns/op) Ratio safe<int8_t> (ns/op) Ratio

Addition

0.61

0.83

1.35

0.65

1.06

Subtraction

0.61

0.83

1.35

0.65

1.06

Multiplication

0.61

0.80

1.31

0.65

1.06

Division

1.65

1.69

1.03

1.68

1.02

Modulo

1.94

1.94

1.00

1.94

1.00

Table 34. 16-bit signed (ratio relative to std::int16_t)
Operation std::int16_t (ns/op) boost::sn::i16 (ns/op) Ratio safe<int16_t> (ns/op) Ratio

Addition

0.61

0.84

1.39

0.83

1.36

Subtraction

0.61

0.84

1.39

0.83

1.36

Multiplication

0.61

0.86

1.40

0.83

1.35

Division

1.69

1.72

1.02

1.82

1.07

Modulo

1.99

1.99

1.00

1.99

1.00

Table 35. 32-bit signed (ratio relative to std::int32_t)
Operation std::int32_t (ns/op) boost::sn::i32 (ns/op) Ratio safe<int32_t> (ns/op) Ratio

Addition

0.51

0.58

1.13

0.70

1.39

Subtraction

0.51

0.58

1.14

0.70

1.38

Multiplication

0.49

0.70

1.44

0.69

1.41

Division

1.74

1.72

0.99

1.73

0.99

Modulo

2.02

2.02

1.00

2.02

1.00

Table 36. 64-bit signed (ratio relative to std::int64_t)
Operation std::int64_t (ns/op) boost::sn::i64 (ns/op) Ratio safe<int64_t> (ns/op) Ratio

Addition

0.51

0.57

1.13

0.70

1.39

Subtraction

0.51

0.57

1.13

0.71

1.40

Multiplication

0.49

0.85

1.71

5.24

10.60

Division

1.76

1.74

0.99

1.74

0.99

Modulo

2.04

2.04

1.00

2.04

1.00

Table 37. 128-bit signed (ratio relative to int128_t)
Operation int128_t (ns/op) boost::sn::i128 (ns/op) Ratio

Addition

1.83

1.90

1.04

Subtraction

1.85

1.92

1.04

Multiplication

1.99

1.93

0.97

Division

5.08

5.30

1.04

Modulo

5.04

5.18

1.03

Unsigned Integers

Table 38. 8-bit unsigned (ratio relative to std::uint8_t)
Operation std::uint8_t (ns/op) boost::sn::u8 (ns/op) Ratio safe<uint8_t> (ns/op) Ratio

Addition

0.90

0.90

0.99

0.93

1.03

Subtraction

0.90

0.90

1.00

0.92

1.02

Multiplication

0.92

0.91

0.99

0.93

1.01

Division

1.65

1.65

1.00

1.64

0.99

Modulo

1.94

1.94

1.00

1.94

1.00

Table 39. 16-bit unsigned (ratio relative to std::uint16_t)
Operation std::uint16_t (ns/op) boost::sn::u16 (ns/op) Ratio safe<uint16_t> (ns/op) Ratio

Addition

0.89

0.89

1.00

0.91

1.02

Subtraction

0.88

0.89

1.00

0.89

1.00

Multiplication

0.90

0.88

0.99

0.95

1.06

Division

1.69

1.70

1.00

1.71

1.01

Modulo

1.99

1.99

1.00

1.99

1.00

Table 40. 32-bit unsigned (ratio relative to std::uint32_t)
Operation std::uint32_t (ns/op) boost::sn::u32 (ns/op) Ratio safe<uint32_t> (ns/op) Ratio

Addition

0.51

0.58

1.14

0.58

1.13

Subtraction

0.51

0.58

1.13

0.57

1.13

Multiplication

0.49

0.61

1.26

0.65

1.34

Division

1.74

1.74

1.00

1.74

1.00

Modulo

2.02

2.02

1.00

2.02

1.00

Table 41. 64-bit unsigned (ratio relative to std::uint64_t)
Operation std::uint64_t (ns/op) boost::sn::u64 (ns/op) Ratio safe<uint64_t> (ns/op) Ratio

Addition

0.51

0.58

1.14

0.58

1.13

Subtraction

0.51

0.57

1.12

0.57

1.13

Multiplication

0.49

0.73

1.48

0.79

1.61

Division

1.76

1.76

1.00

1.76

1.00

Modulo

2.04

2.04

1.00

2.04

1.00

Table 42. 128-bit unsigned (ratio relative to uint128_t)
Operation uint128_t (ns/op) boost::sn::u128 (ns/op) Ratio

Addition

1.85

1.91

1.03

Subtraction

1.85

1.92

1.04

Multiplication

2.01

1.90

0.95

Division

4.67

4.70

1.01

Modulo

4.90

4.93

1.01

macOS ARM64

Run on the GitHub Actions macos-latest runner (Apple Silicon) using Apple Clang in release mode (-O2, C++20).

Floating-Point

Table 43. 32-bit floating point (ratio relative to float)
Operation float (ns/op) boost::sn::f32 (ns/op) Ratio

Addition

3.66

3.76

1.03

Subtraction

3.66

3.46

0.95

Multiplication

3.66

3.80

1.04

Division

3.51

3.48

0.99

Table 44. 64-bit floating point (ratio relative to double)
Operation double (ns/op) boost::sn::f64 (ns/op) Ratio

Addition

3.52

3.58

1.02

Subtraction

3.71

3.74

1.01

Multiplication

3.78

3.78

1.00

Division

3.64

3.69

1.01

Signed Integers

Table 45. 8-bit signed (ratio relative to std::int8_t)
Operation std::int8_t (ns/op) boost::sn::i8 (ns/op) Ratio safe<int8_t> (ns/op) Ratio

Addition

2.28

2.06

0.90

2.25

0.99

Subtraction

2.28

2.08

0.92

2.12

0.93

Multiplication

2.27

2.16

0.95

2.26

1.00

Division

2.21

2.06

0.93

2.29

1.03

Modulo

2.18

2.06

0.95

2.21

1.01

Table 46. 16-bit signed (ratio relative to std::int16_t)
Operation std::int16_t (ns/op) boost::sn::i16 (ns/op) Ratio safe<int16_t> (ns/op) Ratio

Addition

2.21

2.44

1.10

2.05

0.92

Subtraction

2.15

2.27

1.06

2.11

0.98

Multiplication

2.08

2.12

1.02

2.13

1.02

Division

2.29

2.28

0.99

2.08

0.91

Modulo

2.20

2.09

0.95

2.10

0.96

Table 47. 32-bit signed (ratio relative to std::int32_t)
Operation std::int32_t (ns/op) boost::sn::i32 (ns/op) Ratio safe<int32_t> (ns/op) Ratio

Addition

2.26

2.87

1.27

2.08

0.92

Subtraction

2.10

2.70

1.29

2.11

1.01

Multiplication

2.09

2.85

1.37

2.17

1.04

Division

2.16

2.88

1.33

2.11

0.98

Modulo

2.07

2.70

1.30

2.06

1.00

Table 48. 64-bit signed (ratio relative to std::int64_t)
Operation std::int64_t (ns/op) boost::sn::i64 (ns/op) Ratio safe<int64_t> (ns/op) Ratio

Addition

2.22

2.83

1.28

2.21

0.99

Subtraction

2.23

2.81

1.26

2.21

0.99

Multiplication

2.23

2.72

1.22

2.17

0.97

Division

2.27

2.69

1.19

2.19

0.96

Modulo

2.21

2.73

1.24

2.19

0.99

Table 49. 128-bit signed (ratio relative to int128_t)
Operation int128_t (ns/op) boost::sn::i128 (ns/op) Ratio

Addition

2.40

2.62

1.09

Subtraction

2.53

2.38

0.94

Multiplication

2.51

7.64

3.05

Division

6.97

8.22

1.18

Modulo

7.20

7.92

1.10

Unsigned Integers

Table 50. 8-bit unsigned (ratio relative to std::uint8_t)
Operation std::uint8_t (ns/op) boost::sn::u8 (ns/op) Ratio safe<uint8_t> (ns/op) Ratio

Addition

2.45

2.23

0.91

2.25

0.92

Subtraction

2.35

2.23

0.95

2.32

0.99

Multiplication

2.45

2.25

0.92

2.26

0.92

Division

2.41

2.24

0.93

2.26

0.94

Modulo

2.26

2.24

0.99

2.30

1.02

Table 51. 16-bit unsigned (ratio relative to std::uint16_t)
Operation std::uint16_t (ns/op) boost::sn::u16 (ns/op) Ratio safe<uint16_t> (ns/op) Ratio

Addition

2.23

2.33

1.04

2.26

1.01

Subtraction

2.41

2.27

0.94

2.21

0.91

Multiplication

2.57

2.41

0.94

2.07

0.81

Division

2.46

2.79

1.13

2.27

0.92

Modulo

2.51

2.21

0.88

2.19

0.87

Table 52. 32-bit unsigned (ratio relative to std::uint32_t)
Operation std::uint32_t (ns/op) boost::sn::u32 (ns/op) Ratio safe<uint32_t> (ns/op) Ratio

Addition

2.26

2.52

1.12

2.27

1.00

Subtraction

2.32

2.44

1.05

2.13

0.92

Multiplication

2.42

2.41

0.99

2.22

0.91

Division

2.26

2.44

1.08

2.24

0.99

Modulo

2.27

2.63

1.16

2.15

0.95

Table 53. 64-bit unsigned (ratio relative to std::uint64_t)
Operation std::uint64_t (ns/op) boost::sn::u64 (ns/op) Ratio safe<uint64_t> (ns/op) Ratio

Addition

2.12

2.65

1.25

2.07

0.98

Subtraction

2.30

2.52

1.09

2.07

0.90

Multiplication

2.38

2.48

1.04

2.20

0.93

Division

2.19

2.73

1.25

2.09

0.96

Modulo

2.22

2.70

1.21

2.21

0.99

Table 54. 128-bit unsigned (ratio relative to uint128_t)
Operation uint128_t (ns/op) boost::sn::u128 (ns/op) Ratio

Addition

2.57

2.43

0.94

Subtraction

2.67

2.61

0.98

Multiplication

2.55

2.65

1.04

Division

4.13

4.40

1.07

Modulo

4.28

4.47

1.04

Windows x64

Run on the GitHub Actions windows-latest runner using MSVC in release mode (/O2, C++20).

Floating-Point

Table 55. 32-bit floating point (ratio relative to float)
Operation float (ns/op) boost::sn::f32 (ns/op) Ratio

Addition

3.65

3.65

1.00

Subtraction

3.65

3.91

1.07

Multiplication

3.82

3.65

0.95

Division

3.52

3.91

1.11

Table 56. 64-bit floating point (ratio relative to double)
Operation double (ns/op) boost::sn::f64 (ns/op) Ratio

Addition

3.52

4.17

1.19

Subtraction

3.82

3.91

1.02

Multiplication

3.65

3.65

1.00

Division

3.82

3.91

1.02

Signed Integers

Table 57. 8-bit signed (ratio relative to std::int8_t)
Operation std::int8_t (ns/op) boost::sn::i8 (ns/op) Ratio safe<int8_t> (ns/op) Ratio

Addition

1.91

2.08

1.09

2.12

1.11

Subtraction

1.93

2.10

1.09

2.08

1.08

Multiplication

2.08

2.10

1.01

1.91

0.92

Division

2.26

2.43

1.08

2.26

1.00

Modulo

2.26

2.33

1.03

2.26

1.00

Table 58. 16-bit signed (ratio relative to std::int16_t)
Operation std::int16_t (ns/op) boost::sn::i16 (ns/op) Ratio safe<int16_t> (ns/op) Ratio

Addition

1.93

2.12

1.10

1.93

1.00

Subtraction

1.91

2.33

1.22

2.10

1.10

Multiplication

2.08

2.08

1.00

2.08

1.00

Division

2.33

2.43

1.04

2.33

1.00

Modulo

2.26

2.78

1.23

2.08

0.92

Table 59. 32-bit signed (ratio relative to std::int32_t)
Operation std::int32_t (ns/op) boost::sn::i32 (ns/op) Ratio safe<int32_t> (ns/op) Ratio

Addition

1.91

1.91

1.00

1.91

1.00

Subtraction

1.93

1.93

1.00

2.26

1.17

Multiplication

1.56

1.91

1.22

1.91

1.22

Division

1.91

2.89

1.52

2.26

1.18

Modulo

1.93

2.78

1.44

2.26

1.17

Table 60. 64-bit signed (ratio relative to std::int64_t)
Operation std::int64_t (ns/op) boost::sn::i64 (ns/op) Ratio safe<int64_t> (ns/op) Ratio

Addition

1.93

1.91

0.99

1.86

0.96

Subtraction

1.93

1.91

0.99

2.26

1.17

Multiplication

1.93

2.78

1.44

2.89

1.50

Division

2.10

2.12

1.01

2.26

1.08

Modulo

2.10

2.78

1.32

2.33

1.11

Table 61. 128-bit signed (ratio relative to int128_t)
Operation int128_t (ns/op) boost::sn::i128 (ns/op) Ratio

Addition

9.77

3.13

0.32

Subtraction

9.62

3.13

0.33

Multiplication

2.78

13.89

5.00

Division

10.82

13.89

1.28

Modulo

15.63

17.36

1.11

Unsigned Integers

Table 62. 8-bit unsigned (ratio relative to std::uint8_t)
Operation std::uint8_t (ns/op) boost::sn::u8 (ns/op) Ratio safe<uint8_t> (ns/op) Ratio

Addition

1.93

2.08

1.08

2.08

1.08

Subtraction

1.93

2.08

1.08

1.91

0.99

Multiplication

2.08

1.93

0.93

1.91

0.92

Division

1.91

2.31

1.21

1.93

1.01

Modulo

2.10

2.26

1.08

2.08

0.99

Table 63. 16-bit unsigned (ratio relative to std::uint16_t)
Operation std::uint16_t (ns/op) boost::sn::u16 (ns/op) Ratio safe<uint16_t> (ns/op) Ratio

Addition

1.91

2.08

1.09

1.91

1.00

Subtraction

1.91

2.12

1.11

1.91

1.00

Multiplication

1.91

2.08

1.09

2.26

1.18

Division

2.31

2.12

0.92

2.26

0.97

Modulo

1.91

2.26

1.18

2.33

1.22

Table 64. 32-bit unsigned (ratio relative to std::uint32_t)
Operation std::uint32_t (ns/op) boost::sn::u32 (ns/op) Ratio safe<uint32_t> (ns/op) Ratio

Addition

1.93

1.91

0.99

1.56

0.81

Subtraction

1.91

1.93

1.01

1.56

0.82

Multiplication

1.56

1.91

1.22

1.91

1.22

Division

1.86

1.91

1.03

1.91

1.03

Modulo

1.91

1.93

1.01

1.93

1.01

Table 65. 64-bit unsigned (ratio relative to std::uint64_t)
Operation std::uint64_t (ns/op) boost::sn::u64 (ns/op) Ratio safe<uint64_t> (ns/op) Ratio

Addition

1.91

1.91

1.00

1.91

1.00

Subtraction

1.91

1.56

0.82

1.91

1.00

Multiplication

1.93

2.33

1.21

2.78

1.44

Division

2.10

2.12

1.01

2.10

1.00

Modulo

2.33

2.26

0.97

2.33

1.00

Table 66. 128-bit unsigned (ratio relative to uint128_t)
Operation uint128_t (ns/op) boost::sn::u128 (ns/op) Ratio

Addition

2.43

3.13

1.29

Subtraction

2.60

3.13

1.20

Multiplication

3.47

12.15

3.50

Division

2.89

10.82

3.74

Modulo

4.17

3.91

0.94

Windows x86 (32-bit)

Run on the GitHub Actions windows-latest runner using MSVC targeting 32-bit x86 in release mode (/O2, C++20).

Floating-Point

Table 67. 32-bit floating point (ratio relative to float)
Operation float (ns/op) boost::sn::f32 (ns/op) Ratio

Addition

3.65

6.37

1.75

Subtraction

3.65

6.37

1.75

Multiplication

3.82

6.37

1.67

Division

3.82

6.94

1.82

Table 68. 64-bit floating point (ratio relative to double)
Operation double (ns/op) boost::sn::f64 (ns/op) Ratio

Addition

3.82

13.89

3.64

Subtraction

3.91

13.89

3.56

Multiplication

3.65

13.89

3.81

Division

3.82

17.36

4.55

Signed Integers

Table 69. 8-bit signed (ratio relative to std::int8_t)
Operation std::int8_t (ns/op) boost::sn::i8 (ns/op) Ratio safe<int8_t> (ns/op) Ratio

Addition

2.60

3.47

1.33

2.78

1.07

Subtraction

2.43

3.13

1.29

2.78

1.14

Multiplication

3.47

2.78

0.80

2.78

0.80

Division

2.78

3.82

1.38

2.78

1.00

Modulo

3.47

3.65

1.05

2.78

0.80

Table 70. 16-bit signed (ratio relative to std::int16_t)
Operation std::int16_t (ns/op) boost::sn::i16 (ns/op) Ratio safe<int16_t> (ns/op) Ratio

Addition

2.08

2.70

1.30

2.12

1.02

Subtraction

1.87

9.77

5.23

2.12

1.14

Multiplication

2.10

2.12

1.01

2.10

1.00

Division

2.08

2.43

1.17

2.43

1.17

Modulo

2.08

2.78

1.33

2.51

1.20

Table 71. 32-bit signed (ratio relative to std::int32_t)
Operation std::int32_t (ns/op) boost::sn::i32 (ns/op) Ratio safe<int32_t> (ns/op) Ratio

Addition

2.08

2.43

1.17

2.12

1.02

Subtraction

1.91

2.43

1.27

2.43

1.27

Multiplication

1.93

2.43

1.26

2.78

1.44

Division

2.33

2.43

1.04

2.26

0.97

Modulo

2.26

2.43

1.08

2.10

0.93

Table 72. 64-bit signed (ratio relative to std::int64_t)
Operation std::int64_t (ns/op) boost::sn::i64 (ns/op) Ratio safe<int64_t> (ns/op) Ratio

Addition

2.78

5.21

1.87

3.65

1.31

Subtraction

2.78

5.08

1.83

3.65

1.31

Multiplication

4.30

8.33

1.94

8.33

1.94

Division

5.73

6.37

1.11

6.39

1.12

Modulo

4.97

6.39

1.29

5.68

1.14

Table 73. 128-bit signed (ratio relative to int128_t)
Operation int128_t (ns/op) boost::sn::i128 (ns/op) Ratio

Addition

8.68

12.15

1.40

Subtraction

8.79

12.15

1.38

Multiplication

19.10

62.50

3.27

Division

26.04

31.25

1.20

Modulo

26.04

31.25

1.20

Unsigned Integers

Table 74. 8-bit unsigned (ratio relative to std::uint8_t)
Operation std::uint8_t (ns/op) boost::sn::u8 (ns/op) Ratio safe<uint8_t> (ns/op) Ratio

Addition

2.78

3.09

1.11

2.78

1.00

Subtraction

2.70

3.13

1.16

2.78

1.03

Multiplication

3.65

2.95

0.81

2.78

0.76

Division

3.13

3.82

1.22

2.60

0.83

Modulo

3.47

3.82

1.10

2.78

0.80

Table 75. 16-bit unsigned (ratio relative to std::uint16_t)
Operation std::uint16_t (ns/op) boost::sn::u16 (ns/op) Ratio safe<uint16_t> (ns/op) Ratio

Addition

2.33

2.57

1.10

2.08

0.89

Subtraction

2.10

2.26

1.08

2.08

0.99

Multiplication

2.08

2.12

1.02

2.89

1.39

Division

2.26

2.60

1.15

2.08

0.92

Modulo

2.08

2.78

1.33

2.10

1.01

Table 76. 32-bit unsigned (ratio relative to std::uint32_t)
Operation std::uint32_t (ns/op) boost::sn::u32 (ns/op) Ratio safe<uint32_t> (ns/op) Ratio

Addition

2.08

2.33

1.12

2.12

1.02

Subtraction

2.08

2.33

1.12

2.08

1.00

Multiplication

1.93

2.08

1.08

2.33

1.21

Division

2.10

2.12

1.01

2.10

1.00

Modulo

2.12

2.08

0.98

2.10

0.99

Table 77. 64-bit unsigned (ratio relative to std::uint64_t)
Operation std::uint64_t (ns/op) boost::sn::u64 (ns/op) Ratio safe<uint64_t> (ns/op) Ratio

Addition

2.78

3.13

1.12

3.82

1.38

Subtraction

2.78

3.13

1.12

3.13

1.12

Multiplication

4.17

23.44

5.62

7.81

1.87

Division

5.21

5.68

1.09

5.79

1.11

Modulo

4.69

4.97

1.06

4.69

1.00

Table 78. 128-bit unsigned (ratio relative to uint128_t)
Operation uint128_t (ns/op) boost::sn::u128 (ns/op) Ratio

Addition

7.03

15.63

2.22

Subtraction

7.81

17.36

2.22

Multiplication

15.63

70.31

4.50

Division

13.89

31.25

2.25

Modulo

13.89

31.25

2.25

Windows ARM64

Run on the GitHub Actions windows-11-arm runner using MSVC in release mode (/O2, C++20).

Floating-Point

Table 79. 32-bit floating point (ratio relative to float)
Operation float (ns/op) boost::sn::f32 (ns/op) Ratio

Addition

2.10

2.78

1.32

Subtraction

2.10

3.13

1.49

Multiplication

2.12

2.78

1.31

Division

2.12

3.52

1.66

Table 80. 64-bit floating point (ratio relative to double)
Operation double (ns/op) boost::sn::f64 (ns/op) Ratio

Addition

2.08

3.13

1.50

Subtraction

2.10

3.13

1.49

Multiplication

2.08

3.13

1.50

Division

2.08

3.65

1.75

Signed Integers

Table 81. 8-bit signed (ratio relative to std::int8_t)
Operation std::int8_t (ns/op) boost::sn::i8 (ns/op) Ratio safe<int8_t> (ns/op) Ratio

Addition

1.74

1.74

1.00

1.74

1.00

Subtraction

1.74

1.74

1.00

1.74

1.00

Multiplication

1.74

1.74

1.00

1.74

1.00

Division

1.74

1.74

1.00

1.91

1.10

Modulo

1.91

1.93

1.01

1.91

1.00

Table 82. 16-bit signed (ratio relative to std::int16_t)
Operation std::int16_t (ns/op) boost::sn::i16 (ns/op) Ratio safe<int16_t> (ns/op) Ratio

Addition

1.74

1.74

1.00

1.74

1.00

Subtraction

1.74

1.74

1.00

1.74

1.00

Multiplication

1.74

1.74

1.00

1.74

1.00

Division

1.74

1.91

1.10

2.08

1.20

Modulo

1.93

1.93

1.00

2.08

1.08

Table 83. 32-bit signed (ratio relative to std::int32_t)
Operation std::int32_t (ns/op) boost::sn::i32 (ns/op) Ratio safe<int32_t> (ns/op) Ratio

Addition

1.74

1.74

1.00

1.74

1.00

Subtraction

1.74

1.91

1.10

1.74

1.00

Multiplication

1.74

1.74

1.00

1.74

1.00

Division

1.74

1.91

1.10

1.93

1.11

Modulo

2.12

1.91

0.90

2.08

0.98

Table 84. 64-bit signed (ratio relative to std::int64_t)
Operation std::int64_t (ns/op) boost::sn::i64 (ns/op) Ratio safe<int64_t> (ns/op) Ratio

Addition

1.74

1.74

1.00

1.74

1.00

Subtraction

1.91

1.74

0.91

1.74

0.91

Multiplication

1.74

4.30

2.47

5.21

3.00

Division

1.74

1.91

1.10

1.91

1.10

Modulo

2.08

2.08

1.00

2.08

1.00

Table 85. 128-bit signed (ratio relative to int128_t)
Operation int128_t (ns/op) boost::sn::i128 (ns/op) Ratio

Addition

2.78

3.13

1.12

Subtraction

2.78

2.78

1.00

Multiplication

4.17

22.57

5.42

Division

7.10

7.81

1.10

Modulo

7.81

8.33

1.07

Unsigned Integers

Table 86. 8-bit unsigned (ratio relative to std::uint8_t)
Operation std::uint8_t (ns/op) boost::sn::u8 (ns/op) Ratio safe<uint8_t> (ns/op) Ratio

Addition

1.74

1.74

1.00

1.74

1.00

Subtraction

1.74

1.74

1.00

1.74

1.00

Multiplication

1.74

1.74

1.00

1.74

1.00

Division

1.74

1.74

1.00

1.91

1.10

Modulo

1.91

1.91

1.00

1.93

1.01

Table 87. 16-bit unsigned (ratio relative to std::uint16_t)
Operation std::uint16_t (ns/op) boost::sn::u16 (ns/op) Ratio safe<uint16_t> (ns/op) Ratio

Addition

1.74

1.74

1.00

1.74

1.00

Subtraction

1.74

1.74

1.00

1.74

1.00

Multiplication

1.74

1.74

1.00

1.74

1.00

Division

1.74

1.74

1.00

1.91

1.10

Modulo

1.93

1.91

0.99

2.08

1.08

Table 88. 32-bit unsigned (ratio relative to std::uint32_t)
Operation std::uint32_t (ns/op) boost::sn::u32 (ns/op) Ratio safe<uint32_t> (ns/op) Ratio

Addition

1.74

1.74

1.00

1.74

1.00

Subtraction

1.74

1.74

1.00

1.74

1.00

Multiplication

1.74

1.74

1.00

1.74

1.00

Division

1.74

1.74

1.00

1.74

1.00

Modulo

2.10

2.12

1.01

2.08

0.99

Table 89. 64-bit unsigned (ratio relative to std::uint64_t)
Operation std::uint64_t (ns/op) boost::sn::u64 (ns/op) Ratio safe<uint64_t> (ns/op) Ratio

Addition

1.74

1.74

1.00

1.74

1.00

Subtraction

1.74

1.74

1.00

1.74

1.00

Multiplication

1.74

1.74

1.00

5.21

3.00

Division

1.74

1.74

1.00

1.91

1.10

Modulo

2.12

2.12

1.00

2.08

0.98

Table 90. 128-bit unsigned (ratio relative to uint128_t)
Operation uint128_t (ns/op) boost::sn::u128 (ns/op) Ratio

Addition

2.26

2.60

1.15

Subtraction

2.26

2.43

1.08

Multiplication

2.43

19.10

7.86

Division

4.30

4.97

1.16

Modulo

4.69

5.68

1.21