/**
* Tier-0 cheap resource counters, in pure D — the always-available I/O-bound
* signal that needs no `perf_event`, no tracepoints, and no elevated privilege.
*
* Two process-wide cumulative sources are sampled as deltas across a counting
* pass (mirroring `perf.d`'s separate pass, so the reported ns/iter timings are
* never perturbed):
*
* $(LIST
* * `getrusage(RUSAGE_SELF)` — minor/major page faults and voluntary /
* involuntary context switches (the direct blocked-on-I/O vs preempted
* signal);
* * `/proc/self/io` — `syscr`/`syscw` (read/write syscall counts), `rchar`/
* `wchar` (bytes through the syscall layer, cache included) and `read_bytes`/
* `write_bytes` (bytes that actually hit the block device). The gap between
* `rchar` and `read_bytes` is the page-cache-hit signal, for free.
* )
*
* All metrics are `quantitative`: each `timed()` call is bracketed by its own
* pair of cheap snapshots, so — like `perf.d`'s ioctl `ENABLE`/`DISABLE` — the
* untimed `between()` teardown (a `benchCase`'s result release) is excluded from
* the counted window. The snapshots cannot pause, so each bracket's own `/proc`
* read lands inside its window; `tryOpen` calibrates that per-bracket self-cost
* (median of several empty brackets) and `count` reports the workload net of it,
* clamped at zero — so a body that does no I/O reads ≈0, not the instrumentation
* constant. The getrusage-sourced page-fault and context-switch columns carry no
* per-bracket cost. On macOS a darwin body serves the same surface from
* `getrusage`'s maintained BSD-tail fields plus `proc_pid_rusage`'s disk-I/O
* byte counters; elsewhere the group is permanently unavailable.
*/
module (package) sparklessparkles.(package) sparkles.test_runnertest_runner.(module) sparkles.test_runner.tier0Tier-0 cheap resource counters, in pure D — the always-available I/O-bound
signal that needs no perf_event, no tracepoints, and no elevated privilege.
Two process-wide cumulative sources are sampled as deltas across a counting
pass (mirroring perf.d's separate pass, so the reported ns/iter timings are
never perturbed):
getrusage(RUSAGE_SELF) — minor/major page faults and voluntary /
involuntary context switches (the direct blocked-on-I/O vs preempted
signal);
/proc/self/io — syscr/syscw (read/write syscall counts), rchar/
wchar (bytes through the syscall layer, cache included) and read_bytes/
write_bytes (bytes that actually hit the block device). The gap between
rchar and read_bytes is the page-cache-hit signal, for free.
All metrics are quantitative: each timed() call is bracketed by its own
pair of cheap snapshots, so — like perf.d's ioctl ENABLE/DISABLE — the
untimed between() teardown (a benchCase's result release) is excluded from
the counted window. The snapshots cannot pause, so each bracket's own /proc
read lands inside its window; tryOpen calibrates that per-bracket self-cost
(median of several empty brackets) and count reports the workload net of it,
clamped at zero — so a body that does no I/O reads ≈0, not the instrumentation
constant. The getrusage-sourced page-fault and context-switch columns carry no
per-bracket cost. On macOS a darwin body serves the same surface from
getrusage's maintained BSD-tail fields plus proc_pid_rusage's disk-I/O
byte counters; elsewhere the group is permanently unavailable.
tier0;
import (package) sparklessparkles.(package) sparkles.test_runnertest_runner.(module) sparkles.test_runner.capabilityThe capability seam: what can this host measure, as a first-class value.
Every acquisition backend advertises a CapabilityReport after its open
handshake — one Capability flag per survey concern, with a reasoned
CapabilityAbsence entry for everything it cannot deliver on this host,
this run. Capability is a runtime probe result, never a compile-time
assumption: the same binary reports differently under a hardened
perf_event_paranoid, a root-only tracefs, or a PMU-less container.
isCounterBackend names the instance contract CounterGroups has always
demanded of a tier (available/status/capabilities/close/count);
optional primitives (hasSnapshot, hasNamedColumns) unlock optional
behavior by presence, per the DbI guidelines. Construction is deliberately
outside the trait — tryOpen arity varies per tier (perf: bool;
syscalls: bool + names) and stays a per-tier concern of
CounterGroups.open.
The evidence base is the CPU-PMU research catalog
(docs/research/cpu-pmu/backend-proposal.md §2); the shipped shapes
deviate from its sketch where the real surface demanded it (see
docs/specs/test-runner/SPEC.md §6.2).
capability : (enum) sparkles.test_runner.capability.CapabilityOne flag per survey concern (plus real-world sub-splits). Advertised per
backend instance after its open handshake.
Capability, (struct) sparkles.test_runner.capability.CapabilityAbsenceOne absent capability with its host-grounded reason.
CapabilityAbsence,
(struct) sparkles.test_runner.capability.CapabilityReportWhat a backend can deliver on this host, this run: the present flags OR-ed
together, and a reasoned entry per absent flag (in allCapabilities
order). A flag mentioned in neither is outside the backend's domain.
CapabilityReport, (alias) sparkles.test_runner.tier0.has = bool sparkles.test_runner.capability.has(in sparkles.test_runner.capability.CapabilityReport r, sparkles.test_runner.capability.Capability flag) pure nothrow @nogc @safeWhether flag is advertised present.
has, (alias template) sparkles.test_runner.tier0.hasNamedColumns = sparkles.test_runner.capability.hasNamedColumns(B)Optional
dynamic per-column names parallel to a row's counts (the
syscall tier's named tracepoints).
hasNamedColumns, (alias template) sparkles.test_runner.tier0.hasSnapshot = sparkles.test_runner.capability.hasSnapshot(B)Optional
a cheap cumulative snapshot (the snapshot/delta source shape —
tier-0 today, the workload window model tomorrow). Presence, not
declaration, unlocks it.
hasSnapshot, (alias template) sparkles.test_runner.tier0.isCounterBackend = sparkles.test_runner.capability.isCounterBackend(B)The required backend surface — CounterGroups' implicit per-tier contract
made nameable: const-callable probe observers (available, status,
capabilities), resource release, and the bracketed counting pass
returning that backend's row-stats value. The return type of count is
deliberately unconstrained (it differs per tier), as are attributes
(count is a template with inferred attributes).
isCounterBackend,
(alias) sparkles.test_runner.tier0.reasonFor = string sparkles.test_runner.capability.reasonFor(in sparkles.test_runner.capability.CapabilityReport r, sparkles.test_runner.capability.Capability flag) pure nothrow @nogc @safeThe reason flag is absent; null when present or outside the report's
domain. (Returning the second-level slice out of an in report is legal
under dip1000 — scope is non-transitive; a helper returning the
first-level absences slice itself would not compile.)
reasonFor;
/// Per-iteration Tier-0 counter deltas of one counting pass. A field is `nan`
/// when its source could not be read on this machine.
struct (struct) sparkles.test_runner.tier0.Tier0StatsPer-iteration Tier-0 counter deltas of one counting pass. A field is nan
when its source could not be read on this machine.
Tier0Stats
{
ulong (field) ulong sparkles.test_runner.tier0.Tier0Stats.iterscounting-pass iterations
iters; /// counting-pass iterations
double (field) double sparkles.test_runner.tier0.Tier0Stats.minfltminor page faults per iteration (getrusage)
minflt = 0; /// minor page faults per iteration (getrusage)
double (field) double sparkles.test_runner.tier0.Tier0Stats.majfltmajor page faults per iteration (getrusage)
majflt = 0; /// major page faults per iteration (getrusage)
double (field) double sparkles.test_runner.tier0.Tier0Stats.volCsvoluntary context switches per iteration (blocked on I/O)
volCs = 0; /// voluntary context switches per iteration (blocked on I/O)
double (field) double sparkles.test_runner.tier0.Tier0Stats.involCsinvoluntary context switches per iteration (preempted)
involCs = 0; /// involuntary context switches per iteration (preempted)
double (field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr = 0; /// read syscalls per iteration (/proc/self/io)
double (field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw = 0; /// write syscalls per iteration
double (field) double sparkles.test_runner.tier0.Tier0Stats.rdCharsbytes read through the syscall layer (cache included)
rdChars = 0; /// bytes read through the syscall layer (cache included)
double (field) double sparkles.test_runner.tier0.Tier0Stats.wrCharsbytes written through the syscall layer
wrChars = 0; /// bytes written through the syscall layer
double (field) double sparkles.test_runner.tier0.Tier0Stats.rdBytesbytes that actually hit the block device (reads)
rdBytes = 0; /// bytes that actually hit the block device (reads)
double (field) double sparkles.test_runner.tier0.Tier0Stats.wrBytesbytes that actually hit the block device (writes)
wrBytes = 0; /// bytes that actually hit the block device (writes)
}
/// Page-cache hit rate in percent: the fraction of bytes served without touching
/// the block device (`1 − read_bytes ÷ rchar`). `nan` when nothing was read (or
/// `read_bytes` is unavailable). A cold read's kernel readahead can pull more from
/// disk than userspace consumed (`read_bytes > rchar`), so the ratio is clamped to
/// a 0% hit rate rather than reported as `nan` — the cold case the metric reveals.
double double sparkles.test_runner.tier0.cacheHitPercent(in sparkles.test_runner.tier0.Tier0Stats t) pure nothrow @nogc @safePage-cache hit rate in percent: the fraction of bytes served without touching
the block device (1 − read_bytes ÷ rchar). nan when nothing was read (or
read_bytes is unavailable). A cold read's kernel readahead can pull more from
disk than userspace consumed (read_bytes > rchar), so the ratio is clamped to
a 0% hit rate rather than reported as nan — the cold case the metric reveals.
cacheHitPercent(in (struct) sparkles.test_runner.tier0.Tier0StatsPer-iteration Tier-0 counter deltas of one counting pass. A field is nan
when its source could not be read on this machine.
Tier0Stats (parameter) const(sparkles.test_runner.tier0.Tier0Stats) tt) @safe pure nothrow @nogc
{
import (package) stdstd.(package) std.algorithmalgorithm.(module) std.algorithm.comparisonThis is a submodule of std.algorithm.
It contains generic comparison algorithms.
Function Name Description among Checks if a value is among a set of values, e.g. if (v.among(1, 2, 3)) // v is 1, 2 or 3 castSwitch (new A()).castSwitch((A a)=>1,(B b)=>2) returns 1. clamp clamp(1, 3, 6) returns 3. clamp(4, 3, 6) returns 4. cmp cmp("abc", "abcd") is -1, cmp("abc", "aba") is 1, and cmp("abc", "abc") is 0. either Return first parameter p that passes an if (p) test, e.g. either(0, 42, 43) returns 42. equal Compares ranges for element-by-element equality, e.g. equal([1, 2, 3], [1.0, 2.0, 3.0]) returns true. isPermutation isPermutation([1, 2], [2, 1]) returns true. isSameLength isSameLength([1, 2, 3], [4, 5, 6]) returns true. levenshteinDistance levenshteinDistance("kitten", "sitting") returns 3 by using the Levenshtein distance algorithm. levenshteinDistanceAndPath levenshteinDistanceAndPath("kitten", "sitting") returns tuple(3, "snnnsni") by using the Levenshtein distance algorithm. max max(3, 4, 2) returns 4. min min(3, 4, 2) returns 2. mismatch mismatch("oh hi", "ohayo") returns tuple(" hi", "ayo"). predSwitch 2.predSwitch(1, "one", 2, "two", 3, "three") returns "two".
Source
std/algorithm/comparison.d
comparison : (alias template) min = std.algorithm.comparison.min(T...)(T args) if (T.length >= 2 && !is(CommonType!T == void))Iterates the passed arguments and returns the minimum value.
Params:
args = The values to select the minimum from. At least two arguments must
be passed, and they must be comparable with <.
Returns:
The minimum of the passed-in values. The type of the returned value is
the type among the passed arguments that is able to store the smallest value.
If at least one of the arguments is NaN, the result is an unspecified value.
See $(REF minElement, std,algorithm,searching) for examples on how to cope
with NaNs.
See_Also:
$(REF minElement, std,algorithm,searching)
min;
return (parameter) const(sparkles.test_runner.tier0.Tier0Stats) tt.(field) double sparkles.test_runner.tier0.Tier0Stats.rdCharsbytes read through the syscall layer (cache included)
rdChars > 0 && (parameter) const(sparkles.test_runner.tier0.Tier0Stats) tt.(field) double sparkles.test_runner.tier0.Tier0Stats.rdBytesbytes that actually hit the block device (reads)
rdBytes >= 0
? (1 - const(double) std.algorithm.comparison.min!(const(double), const(double))(const(double) a, const(double) b) pure nothrow @nogc @safeIterates the passed arguments and returns the minimum value.
Examples
int a = 5;
short b = 6;
double c = 2;
auto d = min(a, b);
static assert(is(typeof(d) == int));
assert(d == 5);
auto e = min(a, b, c);
static assert(is(typeof(e) == double));
assert(e == 2);
ulong f = 0xffff_ffff_ffff;
const uint g = min(f, 0xffff_0000);
assert(g == 0xffff_0000);
dchar h = 100;
uint i = 101;
static assert(is(typeof(min(h, i)) == dchar));
static assert(is(typeof(min(i, h)) == uint));
assert(min(h, i) == 100);
With arguments of mixed signedness, the return type is the one that can
store the lowest values.
int a = -10;
uint f = 10;
static assert(is(typeof(min(a, f)) == int));
assert(min(a, f) == -10);
User-defined types that support comparison with < are supported.
import std.datetime;
assert(min(Date(2012, 12, 21), Date(1982, 1, 4)) == Date(1982, 1, 4));
assert(min(Date(1982, 1, 4), Date(2012, 12, 21)) == Date(1982, 1, 4));
assert(min(Date(1982, 1, 4), Date.min) == Date.min);
assert(min(Date.min, Date(1982, 1, 4)) == Date.min);
assert(min(Date(1982, 1, 4), Date.max) == Date(1982, 1, 4));
assert(min(Date.max, Date(1982, 1, 4)) == Date(1982, 1, 4));
assert(min(Date.min, Date.max) == Date.min);
assert(min(Date.max, Date.min) == Date.min);
min((parameter) const(sparkles.test_runner.tier0.Tier0Stats) tt.(field) double sparkles.test_runner.tier0.Tier0Stats.rdBytesbytes that actually hit the block device (reads)
rdBytes, (parameter) const(sparkles.test_runner.tier0.Tier0Stats) tt.(field) double sparkles.test_runner.tier0.Tier0Stats.rdCharsbytes read through the syscall layer (cache included)
rdChars) / (parameter) const(sparkles.test_runner.tier0.Tier0Stats) tt.(field) double sparkles.test_runner.tier0.Tier0Stats.rdCharsbytes read through the syscall layer (cache included)
rdChars) * 100 : double.(constant) double double.nan = nannan;
}
@("tier0.cacheHitPercent")
@safe pure nothrow @nogc
unittest
{
import (package) stdstd.(module) std.mathContains the elementary mathematical functions (powers, roots,
and trigonometric functions), and low-level floating-point operations.
Mathematical special functions are available in std.mathspecial.
Category Members Constants E PI PI_2 PI4 M1_PI M2_PI M2_SQRTPI LN10 LN2 LOG2 LOG2E LOG2T LOG10E SQRT2 SQRT1_2 Algebraic abs fabs sqrt cbrt hypot poly nextPow2 truncPow2 Trigonometry sin cos tan asin acos atan atan2 sinh cosh tanh asinh acosh atanh Rounding ceil floor round lround trunc rint lrint nearbyint rndtol quantize Exponentiation & Logarithms pow powmod exp exp2 expm1 ldexp frexp log log2 log10 logb ilogb log1p scalbn Remainder fmod modf remainder remquo Floating-point operations approxEqual feqrel fdim fmax fmin fma isClose nextDown nextUp nextafter NaN getNaNPayload cmp Introspection isFinite isIdentical isInfinity isNaN isNormal isSubnormal signbit sgn copysign isPowerOf2 Hardware Control IeeeFlags ieeeFlags resetIeeeFlags FloatingPointControl
The functionality closely follows the IEEE754-2008 standard for
floating-point arithmetic, including the use of camelCase names rather
than C99-style lower case names. All of these functions behave correctly
when presented with an infinity or NaN.
The following IEEE 'real' formats are currently supported:
64 bit Big-endian 'double' (eg PowerPC)
128 bit Big-endian 'quadruple' (eg SPARC)
64 bit Little-endian 'double' (eg x86-SSE2)
80 bit Little-endian, with implied bit 'real80' (eg x87, Itanium)
128 bit Little-endian 'quadruple' (not implemented on any known processor!)
Non-IEEE 128 bit Big-endian 'doubledouble' (eg PowerPC) has partial support
Unlike C, there is no global 'errno' variable. Consequently, almost all of
these functions are pure nothrow.
Source
std/math/package.d
math : (alias template) isClose = std.math.operations.isClose(T, U, V = CommonType!(FloatingPointBaseType!T, FloatingPointBaseType!U))(T lhs, U rhs, V maxRelDiff = CommonDefaultFor!(T, U), V maxAbsDiff = 0.0)Computes whether two values are approximately equal, admitting a maximum
relative difference, and a maximum absolute difference.
Params:
lhs = First item to compare.
rhs = Second item to compare.
maxRelDiff = Maximum allowable relative difference.
Setting to 0.0 disables this check. Default depends on the type of
lhs and rhs: It is approximately half the number of decimal digits of
precision of the smaller type.
maxAbsDiff = Maximum absolute difference. This is mainly usefull
for comparing values to zero. Setting to 0.0 disables this check.
Defaults to 0.0.
Returns:
true if the two items are approximately equal under either criterium.
It is sufficient, when value satisfies one of the two criteria.
If one item is a range, and the other is a single value, then
the result is the logical and-ing of calling `isClose` on
each element of the ranged item against the single item. If
both items are ranges, then `isClose` returns `true` if
and only if the ranges have the same number of elements and if
`isClose` evaluates to `true` for each pair of elements.
See_Also:
Use $(LREF feqrel) to get the number of equal bits in the mantissa.
isClose, (alias template) isNaN = std.math.traits.isNaN(X)(X x) if (isFloatingPoint!X)Determines if $(D_PARAM x) is NaN.
Params:
x = a floating point number.
Returns:
`true` if $(D_PARAM x) is Nan.
isNaN;
assert(double sparkles.test_runner.tier0.cacheHitPercent(in sparkles.test_runner.tier0.Tier0Stats t) pure nothrow @nogc @safePage-cache hit rate in percent: the fraction of bytes served without touching
the block device (1 − read_bytes ÷ rchar). nan when nothing was read (or
read_bytes is unavailable). A cold read's kernel readahead can pull more from
disk than userspace consumed (read_bytes > rchar), so the ratio is clamped to
a 0% hit rate rather than reported as nan — the cold case the metric reveals.
cacheHitPercent((struct) sparkles.test_runner.tier0.Tier0StatsPer-iteration Tier-0 counter deltas of one counting pass. A field is nan
when its source could not be read on this machine.
Tier0Stats(rdChars: 4096, rdBytes: 0)).bool std.math.operations.isClose!(double, int, real)(double lhs, int rhs, real maxRelDiff = 1e-09L, real maxAbsDiff = 0.0L) pure nothrow @nogc @safeComputes whether two values are approximately equal, admitting a maximum
relative difference, and a maximum absolute difference.
Examples
assert(isClose(1.0,0.999_999_999));
assert(isClose(0.001, 0.000_999_999_999));
assert(isClose(1_000_000_000.0,999_999_999.0));
assert(isClose(17.123_456_789, 17.123_456_78));
assert(!isClose(17.123_456_789, 17.123_45));
// use explicit 3rd parameter for less (or more) accuracy
assert(isClose(17.123_456_789, 17.123_45, 1e-6));
assert(!isClose(17.123_456_789, 17.123_45, 1e-7));
// use 4th parameter when comparing close to zero
assert(!isClose(1e-100, 0.0));
assert(isClose(1e-100, 0.0, 0.0, 1e-90));
assert(!isClose(1e-10, -1e-10));
assert(isClose(1e-10, -1e-10, 0.0, 1e-9));
assert(!isClose(1e-300, 1e-298));
assert(isClose(1e-300, 1e-298, 0.0, 1e-200));
// different default limits for different floating point types
assert(isClose(1.0f, 0.999_99f));
assert(!isClose(1.0, 0.999_99));
static if (real.sizeof > double.sizeof)
assert(!isClose(1.0L, 0.999_999_999L));
assert(isClose([1.0, 2.0, 3.0], [0.999_999_999, 2.000_000_001, 3.0]));
assert(!isClose([1.0, 2.0], [0.999_999_999, 2.000_000_001, 3.0]));
assert(!isClose([1.0, 2.0, 3.0], [0.999_999_999, 2.000_000_001]));
assert(isClose([2.0, 1.999_999_999, 2.000_000_001], 2.0));
assert(isClose(2.0, [2.0, 1.999_999_999, 2.000_000_001]));
isClose(100));
assert(double sparkles.test_runner.tier0.cacheHitPercent(in sparkles.test_runner.tier0.Tier0Stats t) pure nothrow @nogc @safePage-cache hit rate in percent: the fraction of bytes served without touching
the block device (1 − read_bytes ÷ rchar). nan when nothing was read (or
read_bytes is unavailable). A cold read's kernel readahead can pull more from
disk than userspace consumed (read_bytes > rchar), so the ratio is clamped to
a 0% hit rate rather than reported as nan — the cold case the metric reveals.
cacheHitPercent((struct) sparkles.test_runner.tier0.Tier0StatsPer-iteration Tier-0 counter deltas of one counting pass. A field is nan
when its source could not be read on this machine.
Tier0Stats(rdChars: 4096, rdBytes: 1024)).bool std.math.operations.isClose!(double, int, real)(double lhs, int rhs, real maxRelDiff = 1e-09L, real maxAbsDiff = 0.0L) pure nothrow @nogc @safeComputes whether two values are approximately equal, admitting a maximum
relative difference, and a maximum absolute difference.
Examples
assert(isClose(1.0,0.999_999_999));
assert(isClose(0.001, 0.000_999_999_999));
assert(isClose(1_000_000_000.0,999_999_999.0));
assert(isClose(17.123_456_789, 17.123_456_78));
assert(!isClose(17.123_456_789, 17.123_45));
// use explicit 3rd parameter for less (or more) accuracy
assert(isClose(17.123_456_789, 17.123_45, 1e-6));
assert(!isClose(17.123_456_789, 17.123_45, 1e-7));
// use 4th parameter when comparing close to zero
assert(!isClose(1e-100, 0.0));
assert(isClose(1e-100, 0.0, 0.0, 1e-90));
assert(!isClose(1e-10, -1e-10));
assert(isClose(1e-10, -1e-10, 0.0, 1e-9));
assert(!isClose(1e-300, 1e-298));
assert(isClose(1e-300, 1e-298, 0.0, 1e-200));
// different default limits for different floating point types
assert(isClose(1.0f, 0.999_99f));
assert(!isClose(1.0, 0.999_99));
static if (real.sizeof > double.sizeof)
assert(!isClose(1.0L, 0.999_999_999L));
assert(isClose([1.0, 2.0, 3.0], [0.999_999_999, 2.000_000_001, 3.0]));
assert(!isClose([1.0, 2.0], [0.999_999_999, 2.000_000_001, 3.0]));
assert(!isClose([1.0, 2.0, 3.0], [0.999_999_999, 2.000_000_001]));
assert(isClose([2.0, 1.999_999_999, 2.000_000_001], 2.0));
assert(isClose(2.0, [2.0, 1.999_999_999, 2.000_000_001]));
isClose(75));
// Readahead: read_bytes > rchar → clamp to 0%, not nan.
assert(double sparkles.test_runner.tier0.cacheHitPercent(in sparkles.test_runner.tier0.Tier0Stats t) pure nothrow @nogc @safePage-cache hit rate in percent: the fraction of bytes served without touching
the block device (1 − read_bytes ÷ rchar). nan when nothing was read (or
read_bytes is unavailable). A cold read's kernel readahead can pull more from
disk than userspace consumed (read_bytes > rchar), so the ratio is clamped to
a 0% hit rate rather than reported as nan — the cold case the metric reveals.
cacheHitPercent((struct) sparkles.test_runner.tier0.Tier0StatsPer-iteration Tier-0 counter deltas of one counting pass. A field is nan
when its source could not be read on this machine.
Tier0Stats(rdChars: 4096, rdBytes: 8192)).bool std.math.operations.isClose!(double, int, real)(double lhs, int rhs, real maxRelDiff = 1e-09L, real maxAbsDiff = 0.0L) pure nothrow @nogc @safeComputes whether two values are approximately equal, admitting a maximum
relative difference, and a maximum absolute difference.
Examples
assert(isClose(1.0,0.999_999_999));
assert(isClose(0.001, 0.000_999_999_999));
assert(isClose(1_000_000_000.0,999_999_999.0));
assert(isClose(17.123_456_789, 17.123_456_78));
assert(!isClose(17.123_456_789, 17.123_45));
// use explicit 3rd parameter for less (or more) accuracy
assert(isClose(17.123_456_789, 17.123_45, 1e-6));
assert(!isClose(17.123_456_789, 17.123_45, 1e-7));
// use 4th parameter when comparing close to zero
assert(!isClose(1e-100, 0.0));
assert(isClose(1e-100, 0.0, 0.0, 1e-90));
assert(!isClose(1e-10, -1e-10));
assert(isClose(1e-10, -1e-10, 0.0, 1e-9));
assert(!isClose(1e-300, 1e-298));
assert(isClose(1e-300, 1e-298, 0.0, 1e-200));
// different default limits for different floating point types
assert(isClose(1.0f, 0.999_99f));
assert(!isClose(1.0, 0.999_99));
static if (real.sizeof > double.sizeof)
assert(!isClose(1.0L, 0.999_999_999L));
assert(isClose([1.0, 2.0, 3.0], [0.999_999_999, 2.000_000_001, 3.0]));
assert(!isClose([1.0, 2.0], [0.999_999_999, 2.000_000_001, 3.0]));
assert(!isClose([1.0, 2.0, 3.0], [0.999_999_999, 2.000_000_001]));
assert(isClose([2.0, 1.999_999_999, 2.000_000_001], 2.0));
assert(isClose(2.0, [2.0, 1.999_999_999, 2.000_000_001]));
isClose(0));
// Unknown block-device counter (nan) or nothing read → nan.
assert(double sparkles.test_runner.tier0.cacheHitPercent(in sparkles.test_runner.tier0.Tier0Stats t) pure nothrow @nogc @safePage-cache hit rate in percent: the fraction of bytes served without touching
the block device (1 − read_bytes ÷ rchar). nan when nothing was read (or
read_bytes is unavailable). A cold read's kernel readahead can pull more from
disk than userspace consumed (read_bytes > rchar), so the ratio is clamped to
a 0% hit rate rather than reported as nan — the cold case the metric reveals.
cacheHitPercent((struct) sparkles.test_runner.tier0.Tier0StatsPer-iteration Tier-0 counter deltas of one counting pass. A field is nan
when its source could not be read on this machine.
Tier0Stats(rdChars: 4096, rdBytes: double.(constant) double double.nan = nannan)).bool std.math.traits.isNaN!double(double x) pure nothrow @nogc @trustedDetermines if x is NaN.
Examples
assert( isNaN(float.init));
assert( isNaN(-double.init));
assert( isNaN(real.nan));
assert( isNaN(-real.nan));
assert(!isNaN(cast(float) 53.6));
assert(!isNaN(cast(real)-53.6));
isNaN);
assert(double sparkles.test_runner.tier0.cacheHitPercent(in sparkles.test_runner.tier0.Tier0Stats t) pure nothrow @nogc @safePage-cache hit rate in percent: the fraction of bytes served without touching
the block device (1 − read_bytes ÷ rchar). nan when nothing was read (or
read_bytes is unavailable). A cold read's kernel readahead can pull more from
disk than userspace consumed (read_bytes > rchar), so the ratio is clamped to
a 0% hit rate rather than reported as nan — the cold case the metric reveals.
cacheHitPercent((struct) sparkles.test_runner.tier0.Tier0StatsPer-iteration Tier-0 counter deltas of one counting pass. A field is nan
when its source could not be read on this machine.
Tier0Stats(rdChars: 0, rdBytes: 0)).bool std.math.traits.isNaN!double(double x) pure nothrow @nogc @trustedDetermines if x is NaN.
Examples
assert( isNaN(float.init));
assert( isNaN(-double.init));
assert( isNaN(real.nan));
assert( isNaN(-real.nan));
assert(!isNaN(cast(float) 53.6));
assert(!isNaN(cast(real)-53.6));
isNaN);
}
/// Finds `key:` at a line start in a `/proc`-style `key:\tvalue` file and parses
/// the trailing unsigned integer; `-1` when the key is absent or unparsable.
long long sparkles.test_runner.tier0.parseProcField(const(char)[] content, const(char)[] key) pure nothrow @nogc @safeFinds key`:` at a line start in a `/proc`-style key:\tvalue file and parses
the trailing unsigned integer; -1 when the key is absent or unparsable.
parseProcField(const(char)[] (parameter) const(char)[] contentcontent, const(char)[] (parameter) const(char)[] keykey) @safe pure nothrow @nogc
{
(alias) object.size_t = ulongsize_t (local variable) ulong ii = 0;
while ((local variable) ulong ii < (parameter) const(char)[] contentcontent.(field) ulong const(char)[].lengthlength)
{
if ((parameter) const(char)[] contentcontent.(field) ulong const(char)[].lengthlength - (local variable) ulong ii > (parameter) const(char)[] keykey.(field) ulong const(char)[].lengthlength
&& (parameter) const(char)[] contentcontent[(local variable) ulong ii .. (local variable) ulong ii + (parameter) const(char)[] keykey.(field) ulong const(char)[].lengthlength] == (parameter) const(char)[] keykey
&& (parameter) const(char)[] contentcontent[(local variable) ulong ii + (parameter) const(char)[] keykey.(field) ulong const(char)[].lengthlength] == ':')
{
(alias) object.size_t = ulongsize_t (local variable) ulong jj = (local variable) ulong ii + (parameter) const(char)[] keykey.(field) ulong const(char)[].lengthlength + 1;
while ((local variable) ulong jj < (parameter) const(char)[] contentcontent.(field) ulong const(char)[].lengthlength && ((parameter) const(char)[] contentcontent[(local variable) ulong jj] == ' ' || (parameter) const(char)[] contentcontent[(local variable) ulong jj] == '\t'))
(local variable) ulong jj++;
long (local variable) long valuevalue = 0;
bool (local variable) bool anyany;
while ((local variable) ulong jj < (parameter) const(char)[] contentcontent.(field) ulong const(char)[].lengthlength && (parameter) const(char)[] contentcontent[(local variable) ulong jj] >= '0' && (parameter) const(char)[] contentcontent[(local variable) ulong jj] <= '9')
{
(local variable) long valuevalue = (local variable) long valuevalue * 10 + ((parameter) const(char)[] contentcontent[(local variable) ulong jj] - '0');
(local variable) ulong jj++;
(local variable) bool anyany = true;
}
return (local variable) bool anyany ? (local variable) long valuevalue : -1;
}
while ((local variable) ulong ii < (parameter) const(char)[] contentcontent.(field) ulong const(char)[].lengthlength && (parameter) const(char)[] contentcontent[(local variable) ulong ii] != '\n')
(local variable) ulong ii++;
if ((local variable) ulong ii < (parameter) const(char)[] contentcontent.(field) ulong const(char)[].lengthlength)
(local variable) ulong ii++;
}
return -1;
}
@("tier0.parseProcField")
@safe pure nothrow @nogc
unittest
{
static immutable (immutable global) immutable(string) sparkles.test_runner.tier0.__unittest_L116_C1.ioio = "rchar: 4096\nwchar: 0\nsyscr: 7\nread_bytes: 512\n";
assert(long sparkles.test_runner.tier0.parseProcField(const(char)[] content, const(char)[] key) pure nothrow @nogc @safeFinds key`:` at a line start in a `/proc`-style key:\tvalue file and parses
the trailing unsigned integer; -1 when the key is absent or unparsable.
parseProcField((immutable global) immutable(string) sparkles.test_runner.tier0.__unittest_L116_C1.ioio, "rchar") == 4096);
assert(long sparkles.test_runner.tier0.parseProcField(const(char)[] content, const(char)[] key) pure nothrow @nogc @safeFinds key`:` at a line start in a `/proc`-style key:\tvalue file and parses
the trailing unsigned integer; -1 when the key is absent or unparsable.
parseProcField((immutable global) immutable(string) sparkles.test_runner.tier0.__unittest_L116_C1.ioio, "syscr") == 7);
assert(long sparkles.test_runner.tier0.parseProcField(const(char)[] content, const(char)[] key) pure nothrow @nogc @safeFinds key`:` at a line start in a `/proc`-style key:\tvalue file and parses
the trailing unsigned integer; -1 when the key is absent or unparsable.
parseProcField((immutable global) immutable(string) sparkles.test_runner.tier0.__unittest_L116_C1.ioio, "read_bytes") == 512);
assert(long sparkles.test_runner.tier0.parseProcField(const(char)[] content, const(char)[] key) pure nothrow @nogc @safeFinds key`:` at a line start in a `/proc`-style key:\tvalue file and parses
the trailing unsigned integer; -1 when the key is absent or unparsable.
parseProcField((immutable global) immutable(string) sparkles.test_runner.tier0.__unittest_L116_C1.ioio, "write_bytes") == -1); // absent
assert(long sparkles.test_runner.tier0.parseProcField(const(char)[] content, const(char)[] key) pure nothrow @nogc @safeFinds key`:` at a line start in a `/proc`-style key:\tvalue file and parses
the trailing unsigned integer; -1 when the key is absent or unparsable.
parseProcField((immutable global) immutable(string) sparkles.test_runner.tier0.__unittest_L116_C1.ioio, "char") == -1); // not a line-start key
}
/// Divides raw before/after readings into per-iteration `Tier0Stats`; a source
/// unavailable in either reading yields `nan` for its fields.
package (struct) sparkles.test_runner.tier0.Tier0StatsPer-iteration Tier-0 counter deltas of one counting pass. A field is nan
when its source could not be read on this machine.
Tier0Stats sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.deltaStats(in sparkles.test_runner.tier0.Tier0Reading a, in sparkles.test_runner.tier0.Tier0Reading b, uint iters) pure nothrow @nogc @safeDivides raw before/after readings into per-iteration Tier0Stats; a source
unavailable in either reading yields nan for its fields.
deltaStats(in (struct) sparkles.test_runner.tier0.Tier0ReadingA single instant's raw cumulative counters.
Tier0Reading (parameter) const(sparkles.test_runner.tier0.Tier0Reading) aa, in (struct) sparkles.test_runner.tier0.Tier0ReadingA single instant's raw cumulative counters.
Tier0Reading (parameter) const(sparkles.test_runner.tier0.Tier0Reading) bb, uint (parameter) uint itersiters)
@safe pure nothrow @nogc
in ((parameter) uint itersiters > 0)
{
const (local variable) const(double) invinv = 1.0 / (parameter) uint itersiters;
(struct) sparkles.test_runner.tier0.Tier0StatsPer-iteration Tier-0 counter deltas of one counting pass. A field is nan
when its source could not be read on this machine.
Tier0Stats (local variable) sparkles.test_runner.tier0.Tier0Stats ss;
(local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) ulong sparkles.test_runner.tier0.Tier0Stats.iterscounting-pass iterations
iters = (parameter) uint itersiters;
// Per-field guard: a reading whose field is absent (a kernel
// omitting/restricting it, or a platform whose libc reports but never
// maintains it — XNU's rusage tail leaves ru_nvcsw permanently 0) is
// -1, and an absent counter must read nan, never a fabricated 0 delta
// (which would also feed a fake 100% cache-hit figure).
static double double sparkles.test_runner.tier0.deltaStats.guarded(long av, long bv, double inv) pure nothrow @nogc @safeguarded(long (parameter) long avav, long (parameter) long bvbv, double (parameter) double invinv) @safe pure nothrow @nogc
=> (parameter) long avav >= 0 && (parameter) long bvbv >= 0 ? ((parameter) long bvbv - (parameter) long avav) * (parameter) double invinv : double.(constant) double double.nan = nannan;
if ((parameter) const(sparkles.test_runner.tier0.Tier0Reading) aa.(field) bool sparkles.test_runner.tier0.Tier0Reading.rusageOkrusageOk && (parameter) const(sparkles.test_runner.tier0.Tier0Reading) bb.(field) bool sparkles.test_runner.tier0.Tier0Reading.rusageOkrusageOk)
{
(local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.minfltminor page faults per iteration (getrusage)
minflt = double sparkles.test_runner.tier0.deltaStats.guarded(long av, long bv, double inv) pure nothrow @nogc @safeguarded((parameter) const(sparkles.test_runner.tier0.Tier0Reading) aa.(field) long sparkles.test_runner.tier0.Tier0Reading.minfltminflt, (parameter) const(sparkles.test_runner.tier0.Tier0Reading) bb.(field) long sparkles.test_runner.tier0.Tier0Reading.minfltminflt, (local variable) const(double) invinv);
(local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.majfltmajor page faults per iteration (getrusage)
majflt = double sparkles.test_runner.tier0.deltaStats.guarded(long av, long bv, double inv) pure nothrow @nogc @safeguarded((parameter) const(sparkles.test_runner.tier0.Tier0Reading) aa.(field) long sparkles.test_runner.tier0.Tier0Reading.majfltmajflt, (parameter) const(sparkles.test_runner.tier0.Tier0Reading) bb.(field) long sparkles.test_runner.tier0.Tier0Reading.majfltmajflt, (local variable) const(double) invinv);
(local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.volCsvoluntary context switches per iteration (blocked on I/O)
volCs = double sparkles.test_runner.tier0.deltaStats.guarded(long av, long bv, double inv) pure nothrow @nogc @safeguarded((parameter) const(sparkles.test_runner.tier0.Tier0Reading) aa.(field) long sparkles.test_runner.tier0.Tier0Reading.volCsvolCs, (parameter) const(sparkles.test_runner.tier0.Tier0Reading) bb.(field) long sparkles.test_runner.tier0.Tier0Reading.volCsvolCs, (local variable) const(double) invinv);
(local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.involCsinvoluntary context switches per iteration (preempted)
involCs = double sparkles.test_runner.tier0.deltaStats.guarded(long av, long bv, double inv) pure nothrow @nogc @safeguarded((parameter) const(sparkles.test_runner.tier0.Tier0Reading) aa.(field) long sparkles.test_runner.tier0.Tier0Reading.involCsgetrusage
involCs, (parameter) const(sparkles.test_runner.tier0.Tier0Reading) bb.(field) long sparkles.test_runner.tier0.Tier0Reading.involCsgetrusage
involCs, (local variable) const(double) invinv);
}
else
(local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.minfltminor page faults per iteration (getrusage)
minflt = (local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.majfltmajor page faults per iteration (getrusage)
majflt = (local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.volCsvoluntary context switches per iteration (blocked on I/O)
volCs = (local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.involCsinvoluntary context switches per iteration (preempted)
involCs = double.(constant) double double.nan = nannan;
if ((parameter) const(sparkles.test_runner.tier0.Tier0Reading) aa.(field) bool sparkles.test_runner.tier0.Tier0Reading.ioOkioOk && (parameter) const(sparkles.test_runner.tier0.Tier0Reading) bb.(field) bool sparkles.test_runner.tier0.Tier0Reading.ioOkioOk)
{
(local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr = double sparkles.test_runner.tier0.deltaStats.guarded(long av, long bv, double inv) pure nothrow @nogc @safeguarded((parameter) const(sparkles.test_runner.tier0.Tier0Reading) aa.(field) long sparkles.test_runner.tier0.Tier0Reading.syscrsyscr, (parameter) const(sparkles.test_runner.tier0.Tier0Reading) bb.(field) long sparkles.test_runner.tier0.Tier0Reading.syscrsyscr, (local variable) const(double) invinv);
(local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw = double sparkles.test_runner.tier0.deltaStats.guarded(long av, long bv, double inv) pure nothrow @nogc @safeguarded((parameter) const(sparkles.test_runner.tier0.Tier0Reading) aa.(field) long sparkles.test_runner.tier0.Tier0Reading.syscwsyscw, (parameter) const(sparkles.test_runner.tier0.Tier0Reading) bb.(field) long sparkles.test_runner.tier0.Tier0Reading.syscwsyscw, (local variable) const(double) invinv);
(local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.rdCharsbytes read through the syscall layer (cache included)
rdChars = double sparkles.test_runner.tier0.deltaStats.guarded(long av, long bv, double inv) pure nothrow @nogc @safeguarded((parameter) const(sparkles.test_runner.tier0.Tier0Reading) aa.(field) long sparkles.test_runner.tier0.Tier0Reading.rdCharsrdChars, (parameter) const(sparkles.test_runner.tier0.Tier0Reading) bb.(field) long sparkles.test_runner.tier0.Tier0Reading.rdCharsrdChars, (local variable) const(double) invinv);
(local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.wrCharsbytes written through the syscall layer
wrChars = double sparkles.test_runner.tier0.deltaStats.guarded(long av, long bv, double inv) pure nothrow @nogc @safeguarded((parameter) const(sparkles.test_runner.tier0.Tier0Reading) aa.(field) long sparkles.test_runner.tier0.Tier0Reading.wrCharswrChars, (parameter) const(sparkles.test_runner.tier0.Tier0Reading) bb.(field) long sparkles.test_runner.tier0.Tier0Reading.wrCharswrChars, (local variable) const(double) invinv);
(local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.rdBytesbytes that actually hit the block device (reads)
rdBytes = double sparkles.test_runner.tier0.deltaStats.guarded(long av, long bv, double inv) pure nothrow @nogc @safeguarded((parameter) const(sparkles.test_runner.tier0.Tier0Reading) aa.(field) long sparkles.test_runner.tier0.Tier0Reading.rdBytesrdBytes, (parameter) const(sparkles.test_runner.tier0.Tier0Reading) bb.(field) long sparkles.test_runner.tier0.Tier0Reading.rdBytesrdBytes, (local variable) const(double) invinv);
(local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.wrBytesbytes that actually hit the block device (writes)
wrBytes = double sparkles.test_runner.tier0.deltaStats.guarded(long av, long bv, double inv) pure nothrow @nogc @safeguarded((parameter) const(sparkles.test_runner.tier0.Tier0Reading) aa.(field) long sparkles.test_runner.tier0.Tier0Reading.wrBytes/proc/self/io
wrBytes, (parameter) const(sparkles.test_runner.tier0.Tier0Reading) bb.(field) long sparkles.test_runner.tier0.Tier0Reading.wrBytes/proc/self/io
wrBytes, (local variable) const(double) invinv);
}
else
(local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr = (local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw = (local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.rdCharsbytes read through the syscall layer (cache included)
rdChars = (local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.wrCharsbytes written through the syscall layer
wrChars = (local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.rdBytesbytes that actually hit the block device (reads)
rdBytes = (local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.wrBytesbytes that actually hit the block device (writes)
wrBytes = double.(constant) double double.nan = nannan;
return (local variable) sparkles.test_runner.tier0.Tier0Stats ss;
}
@("tier0.deltaStats.absentBlockDeviceFields")
@safe pure nothrow @nogc
unittest
{
import (package) stdstd.(module) std.mathContains the elementary mathematical functions (powers, roots,
and trigonometric functions), and low-level floating-point operations.
Mathematical special functions are available in std.mathspecial.
Category Members Constants E PI PI_2 PI4 M1_PI M2_PI M2_SQRTPI LN10 LN2 LOG2 LOG2E LOG2T LOG10E SQRT2 SQRT1_2 Algebraic abs fabs sqrt cbrt hypot poly nextPow2 truncPow2 Trigonometry sin cos tan asin acos atan atan2 sinh cosh tanh asinh acosh atanh Rounding ceil floor round lround trunc rint lrint nearbyint rndtol quantize Exponentiation & Logarithms pow powmod exp exp2 expm1 ldexp frexp log log2 log10 logb ilogb log1p scalbn Remainder fmod modf remainder remquo Floating-point operations approxEqual feqrel fdim fmax fmin fma isClose nextDown nextUp nextafter NaN getNaNPayload cmp Introspection isFinite isIdentical isInfinity isNaN isNormal isSubnormal signbit sgn copysign isPowerOf2 Hardware Control IeeeFlags ieeeFlags resetIeeeFlags FloatingPointControl
The functionality closely follows the IEEE754-2008 standard for
floating-point arithmetic, including the use of camelCase names rather
than C99-style lower case names. All of these functions behave correctly
when presented with an infinity or NaN.
The following IEEE 'real' formats are currently supported:
64 bit Big-endian 'double' (eg PowerPC)
128 bit Big-endian 'quadruple' (eg SPARC)
64 bit Little-endian 'double' (eg x86-SSE2)
80 bit Little-endian, with implied bit 'real80' (eg x87, Itanium)
128 bit Little-endian 'quadruple' (not implemented on any known processor!)
Non-IEEE 128 bit Big-endian 'doubledouble' (eg PowerPC) has partial support
Unlike C, there is no global 'errno' variable. Consequently, almost all of
these functions are pure nothrow.
Source
std/math/package.d
math : (alias template) isClose = std.math.operations.isClose(T, U, V = CommonType!(FloatingPointBaseType!T, FloatingPointBaseType!U))(T lhs, U rhs, V maxRelDiff = CommonDefaultFor!(T, U), V maxAbsDiff = 0.0)Computes whether two values are approximately equal, admitting a maximum
relative difference, and a maximum absolute difference.
Params:
lhs = First item to compare.
rhs = Second item to compare.
maxRelDiff = Maximum allowable relative difference.
Setting to 0.0 disables this check. Default depends on the type of
lhs and rhs: It is approximately half the number of decimal digits of
precision of the smaller type.
maxAbsDiff = Maximum absolute difference. This is mainly usefull
for comparing values to zero. Setting to 0.0 disables this check.
Defaults to 0.0.
Returns:
true if the two items are approximately equal under either criterium.
It is sufficient, when value satisfies one of the two criteria.
If one item is a range, and the other is a single value, then
the result is the logical and-ing of calling `isClose` on
each element of the ranged item against the single item. If
both items are ranges, then `isClose` returns `true` if
and only if the ranges have the same number of elements and if
`isClose` evaluates to `true` for each pair of elements.
See_Also:
Use $(LREF feqrel) to get the number of equal bits in the mantissa.
isClose, (alias template) isNaN = std.math.traits.isNaN(X)(X x) if (isFloatingPoint!X)Determines if $(D_PARAM x) is NaN.
Params:
x = a floating point number.
Returns:
`true` if $(D_PARAM x) is Nan.
isNaN;
// A kernel without CONFIG_TASK_IO_ACCOUNTING: rchar/syscr present, read_bytes/
// write_bytes absent (-1) — ioOk is still true.
const (local variable) const(sparkles.test_runner.tier0.Tier0Reading) aa = (struct) sparkles.test_runner.tier0.Tier0ReadingA single instant's raw cumulative counters.
Tier0Reading(syscr: 10, syscw: 2, rdChars: 4096, wrChars: 0,
rdBytes: -1, wrBytes: -1, ioOk: true);
const (local variable) const(sparkles.test_runner.tier0.Tier0Reading) bb = (struct) sparkles.test_runner.tier0.Tier0ReadingA single instant's raw cumulative counters.
Tier0Reading(syscr: 20, syscw: 4, rdChars: 8192, wrChars: 0,
rdBytes: -1, wrBytes: -1, ioOk: true);
const (local variable) const(sparkles.test_runner.tier0.Tier0Stats) ss = sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.deltaStats(in sparkles.test_runner.tier0.Tier0Reading a, in sparkles.test_runner.tier0.Tier0Reading b, uint iters) pure nothrow @nogc @safeDivides raw before/after readings into per-iteration Tier0Stats; a source
unavailable in either reading yields nan for its fields.
deltaStats((local variable) const(sparkles.test_runner.tier0.Tier0Reading) aa, (local variable) const(sparkles.test_runner.tier0.Tier0Reading) bb, 2);
assert((local variable) const(sparkles.test_runner.tier0.Tier0Stats) ss.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr.bool std.math.operations.isClose!(const(double), int, real)(const(double) lhs, int rhs, real maxRelDiff = 1e-09L, real maxAbsDiff = 0.0L) pure nothrow @nogc @safeComputes whether two values are approximately equal, admitting a maximum
relative difference, and a maximum absolute difference.
Examples
assert(isClose(1.0,0.999_999_999));
assert(isClose(0.001, 0.000_999_999_999));
assert(isClose(1_000_000_000.0,999_999_999.0));
assert(isClose(17.123_456_789, 17.123_456_78));
assert(!isClose(17.123_456_789, 17.123_45));
// use explicit 3rd parameter for less (or more) accuracy
assert(isClose(17.123_456_789, 17.123_45, 1e-6));
assert(!isClose(17.123_456_789, 17.123_45, 1e-7));
// use 4th parameter when comparing close to zero
assert(!isClose(1e-100, 0.0));
assert(isClose(1e-100, 0.0, 0.0, 1e-90));
assert(!isClose(1e-10, -1e-10));
assert(isClose(1e-10, -1e-10, 0.0, 1e-9));
assert(!isClose(1e-300, 1e-298));
assert(isClose(1e-300, 1e-298, 0.0, 1e-200));
// different default limits for different floating point types
assert(isClose(1.0f, 0.999_99f));
assert(!isClose(1.0, 0.999_99));
static if (real.sizeof > double.sizeof)
assert(!isClose(1.0L, 0.999_999_999L));
assert(isClose([1.0, 2.0, 3.0], [0.999_999_999, 2.000_000_001, 3.0]));
assert(!isClose([1.0, 2.0], [0.999_999_999, 2.000_000_001, 3.0]));
assert(!isClose([1.0, 2.0, 3.0], [0.999_999_999, 2.000_000_001]));
assert(isClose([2.0, 1.999_999_999, 2.000_000_001], 2.0));
assert(isClose(2.0, [2.0, 1.999_999_999, 2.000_000_001]));
isClose(5) && (local variable) const(sparkles.test_runner.tier0.Tier0Stats) ss.(field) double sparkles.test_runner.tier0.Tier0Stats.rdCharsbytes read through the syscall layer (cache included)
rdChars.bool std.math.operations.isClose!(const(double), int, real)(const(double) lhs, int rhs, real maxRelDiff = 1e-09L, real maxAbsDiff = 0.0L) pure nothrow @nogc @safeComputes whether two values are approximately equal, admitting a maximum
relative difference, and a maximum absolute difference.
Examples
assert(isClose(1.0,0.999_999_999));
assert(isClose(0.001, 0.000_999_999_999));
assert(isClose(1_000_000_000.0,999_999_999.0));
assert(isClose(17.123_456_789, 17.123_456_78));
assert(!isClose(17.123_456_789, 17.123_45));
// use explicit 3rd parameter for less (or more) accuracy
assert(isClose(17.123_456_789, 17.123_45, 1e-6));
assert(!isClose(17.123_456_789, 17.123_45, 1e-7));
// use 4th parameter when comparing close to zero
assert(!isClose(1e-100, 0.0));
assert(isClose(1e-100, 0.0, 0.0, 1e-90));
assert(!isClose(1e-10, -1e-10));
assert(isClose(1e-10, -1e-10, 0.0, 1e-9));
assert(!isClose(1e-300, 1e-298));
assert(isClose(1e-300, 1e-298, 0.0, 1e-200));
// different default limits for different floating point types
assert(isClose(1.0f, 0.999_99f));
assert(!isClose(1.0, 0.999_99));
static if (real.sizeof > double.sizeof)
assert(!isClose(1.0L, 0.999_999_999L));
assert(isClose([1.0, 2.0, 3.0], [0.999_999_999, 2.000_000_001, 3.0]));
assert(!isClose([1.0, 2.0], [0.999_999_999, 2.000_000_001, 3.0]));
assert(!isClose([1.0, 2.0, 3.0], [0.999_999_999, 2.000_000_001]));
assert(isClose([2.0, 1.999_999_999, 2.000_000_001], 2.0));
assert(isClose(2.0, [2.0, 1.999_999_999, 2.000_000_001]));
isClose(2048));
assert((local variable) const(sparkles.test_runner.tier0.Tier0Stats) ss.(field) double sparkles.test_runner.tier0.Tier0Stats.rdBytesbytes that actually hit the block device (reads)
rdBytes.bool std.math.traits.isNaN!(const(double))(const(double) x) pure nothrow @nogc @trustedDetermines if x is NaN.
Examples
assert( isNaN(float.init));
assert( isNaN(-double.init));
assert( isNaN(real.nan));
assert( isNaN(-real.nan));
assert(!isNaN(cast(float) 53.6));
assert(!isNaN(cast(real)-53.6));
isNaN && (local variable) const(sparkles.test_runner.tier0.Tier0Stats) ss.(field) double sparkles.test_runner.tier0.Tier0Stats.wrBytesbytes that actually hit the block device (writes)
wrBytes.bool std.math.traits.isNaN!(const(double))(const(double) x) pure nothrow @nogc @trustedDetermines if x is NaN.
Examples
assert( isNaN(float.init));
assert( isNaN(-double.init));
assert( isNaN(real.nan));
assert( isNaN(-real.nan));
assert(!isNaN(cast(float) 53.6));
assert(!isNaN(cast(real)-53.6));
isNaN, "absent block-device fields → nan");
assert(double sparkles.test_runner.tier0.cacheHitPercent(in sparkles.test_runner.tier0.Tier0Stats t) pure nothrow @nogc @safePage-cache hit rate in percent: the fraction of bytes served without touching
the block device (1 − read_bytes ÷ rchar). nan when nothing was read (or
read_bytes is unavailable). A cold read's kernel readahead can pull more from
disk than userspace consumed (read_bytes > rchar), so the ratio is clamped to
a 0% hit rate rather than reported as nan — the cold case the metric reveals.
cacheHitPercent((local variable) const(sparkles.test_runner.tier0.Tier0Stats) ss).bool std.math.traits.isNaN!double(double x) pure nothrow @nogc @trustedDetermines if x is NaN.
Examples
assert( isNaN(float.init));
assert( isNaN(-double.init));
assert( isNaN(real.nan));
assert( isNaN(-real.nan));
assert(!isNaN(cast(float) 53.6));
assert(!isNaN(cast(real)-53.6));
isNaN, "cache-hit unknown when read_bytes absent");
}
/// A single instant's raw cumulative counters.
struct (struct) sparkles.test_runner.tier0.Tier0ReadingA single instant's raw cumulative counters.
Tier0Reading
{
long (field) long sparkles.test_runner.tier0.Tier0Reading.minfltminflt, (field) long sparkles.test_runner.tier0.Tier0Reading.majfltmajflt, (field) long sparkles.test_runner.tier0.Tier0Reading.volCsvolCs, (field) long sparkles.test_runner.tier0.Tier0Reading.involCsgetrusage
involCs; /// getrusage
long (field) long sparkles.test_runner.tier0.Tier0Reading.syscrsyscr, (field) long sparkles.test_runner.tier0.Tier0Reading.syscwsyscw, (field) long sparkles.test_runner.tier0.Tier0Reading.rdCharsrdChars, (field) long sparkles.test_runner.tier0.Tier0Reading.wrCharswrChars, (field) long sparkles.test_runner.tier0.Tier0Reading.rdBytesrdBytes, (field) long sparkles.test_runner.tier0.Tier0Reading.wrBytes/proc/self/io
wrBytes; /// /proc/self/io
bool (field) bool sparkles.test_runner.tier0.Tier0Reading.rusageOkrusageOk, (field) bool sparkles.test_runner.tier0.Tier0Reading.ioOkioOk;
}
version (linuxlinux)
{
import (package) corecore.(package) core.syssys.(package) core.sys.posixposix.(package) core.sys.posix.syssys.(module) core.sys.posix.sys.resourceD header file for POSIX.
resource : (alias) sparkles.test_runner.tier0.getrusage = int core.sys.posix.sys.resource.getrusage(int, core.sys.posix.sys.resource.rusage*) nothrow @nogcgetrusage, (struct) core.sys.posix.sys.resource.rusagerusage, (alias enum value) sparkles.test_runner.tier0.RUSAGE_SELF = core.sys.posix.sys.resource.RUSAGE_SELF = 0RUSAGE_SELF;
/// The Tier-0 counter group. No fds; `count` snapshots the cumulative
/// counters around each iteration. Carries the calibrated per-bracket
/// self-cost of the snapshots themselves (see `calibrateSelfCost`).
struct (struct) sparkles.test_runner.tier0.Tier0GroupThe Tier-0 counter group. No fds; count snapshots the cumulative
counters around each iteration. Carries the calibrated per-bracket
self-cost of the snapshots themselves (see calibrateSelfCost).
Tier0Group
{
private bool (field) bool sparkles.test_runner.tier0.Tier0Group.enabledenabled;
private (struct) sparkles.test_runner.tier0.Tier0StatsPer-iteration Tier-0 counter deltas of one counting pass. A field is nan
when its source could not be read on this machine.
Tier0Stats (field) sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.selfCostper-bracket snapshot cost; 0 = uncalibrated
selfCost; /// per-bracket snapshot cost; 0 = uncalibrated
/// Whether Tier-0 counters will be collected (Linux and requested).
bool bool sparkles.test_runner.tier0.Tier0Group.available() const pure nothrow @nogc @safeWhether Tier-0 counters will be collected (Linux and requested).
available() const @safe pure nothrow @nogc => (field) bool sparkles.test_runner.tier0.Tier0Group.enabledenabled;
/// Human-readable availability, for a report header.
(alias) object.string = stringstring string sparkles.test_runner.tier0.Tier0Group.status() const pure nothrow @safeHuman-readable availability, for a report header.
status() const @safe pure nothrow
=> (field) bool sparkles.test_runner.tier0.Tier0Group.enabledenabled ? "getrusage + /proc/self/io" : "not requested";
/// What this backend can deliver: process-scope resource counting —
/// present whenever requested (Linux needs no privilege for it).
(struct) sparkles.test_runner.capability.CapabilityReportWhat a backend can deliver on this host, this run: the present flags OR-ed
together, and a reasoned entry per absent flag (in allCapabilities
order). A flag mentioned in neither is outside the backend's domain.
CapabilityReport sparkles.test_runner.capability.CapabilityReport sparkles.test_runner.tier0.Tier0Group.capabilities() const pure nothrow @nogc @safeWhat this backend can deliver: process-scope resource counting —
present whenever requested (Linux needs no privilege for it).
capabilities() const @safe pure nothrow @nogc
=> (field) bool sparkles.test_runner.tier0.Tier0Group.enabledenabled
? (struct) sparkles.test_runner.capability.CapabilityReportWhat a backend can deliver on this host, this run: the present flags OR-ed
together, and a reasoned entry per absent flag (in allCapabilities
order). A flag mentioned in neither is outside the backend's domain.
CapabilityReport((enum) sparkles.test_runner.capability.CapabilityOne flag per survey concern (plus real-world sub-splits). Advertised per
backend instance after its open handshake.
Capability.(enum value) sparkles.test_runner.capability.Capability.counting = 1uconcern 1: scalar counting
counting, null)
: (struct) sparkles.test_runner.capability.CapabilityReportWhat a backend can deliver on this host, this run: the present flags OR-ed
together, and a reasoned entry per absent flag (in allCapabilities
order). A flag mentioned in neither is outside the backend's domain.
CapabilityReport((enum) sparkles.test_runner.capability.CapabilityOne flag per survey concern (plus real-world sub-splits). Advertised per
backend instance after its open handshake.
Capability.(enum value) sparkles.test_runner.capability.Capability.none = 0unone, (immutable global) immutable(sparkles.test_runner.capability.CapabilityAbsence[1]) sparkles.test_runner.tier0.Tier0Group.notRequestedAbsencenotRequestedAbsence[]);
private static immutable (struct) sparkles.test_runner.capability.CapabilityAbsenceOne absent capability with its host-grounded reason.
CapabilityAbsence[1] (immutable global) immutable(sparkles.test_runner.capability.CapabilityAbsence[1]) sparkles.test_runner.tier0.Tier0Group.notRequestedAbsencenotRequestedAbsence = [
(struct) sparkles.test_runner.capability.CapabilityAbsenceOne absent capability with its host-grounded reason.
CapabilityAbsence((enum) sparkles.test_runner.capability.CapabilityOne flag per survey concern (plus real-world sub-splits). Advertised per
backend instance after its open handshake.
Capability.(enum value) sparkles.test_runner.capability.Capability.counting = 1uconcern 1: scalar counting
counting, "not requested"),
];
/// Enables collection when `enabled` and calibrates the snapshot
/// self-cost; otherwise an unavailable group (mirrors
/// `PerfGroup.tryOpen(false)`), so the same call sites work.
static (struct) sparkles.test_runner.tier0.Tier0GroupThe Tier-0 counter group. No fds; count snapshots the cumulative
counters around each iteration. Carries the calibrated per-bracket
self-cost of the snapshots themselves (see calibrateSelfCost).
Tier0Group sparkles.test_runner.tier0.Tier0Group sparkles.test_runner.tier0.Tier0Group.tryOpen(bool enabled) @safeEnables collection when enabled and calibrates the snapshot
self-cost; otherwise an unavailable group (mirrors
PerfGroup.tryOpen(false)), so the same call sites work.
tryOpen(bool (parameter) bool enabledenabled) @safe
{
auto (local variable) sparkles.test_runner.tier0.Tier0Group gg = (struct) sparkles.test_runner.tier0.Tier0GroupThe Tier-0 counter group. No fds; count snapshots the cumulative
counters around each iteration. Carries the calibrated per-bracket
self-cost of the snapshots themselves (see calibrateSelfCost).
Tier0Group((parameter) bool enabledenabled);
if ((parameter) bool enabledenabled)
(local variable) sparkles.test_runner.tier0.Tier0Group gg.(field) sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.selfCostper-bracket snapshot cost; 0 = uncalibrated
selfCost = (local variable) sparkles.test_runner.tier0.Tier0Group gg.sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.calibrateSelfCost() @safeThe per-bracket cost of the bracketing snapshots themselves: each
start/end pair puts one /proc/self/io read (~1 syscr, a few
hundred rchar bytes) inside its own window. Measured as the median
of several empty brackets so count can subtract it. Page-fault and
context-switch fields stay 0 — they carry no steady-state bracket
cost, and subtracting sporadic noise would bias real counts.
calibrateSelfCost();
return (local variable) sparkles.test_runner.tier0.Tier0Group gg;
}
/// The per-bracket cost of the bracketing snapshots themselves: each
/// `start`/`end` pair puts one `/proc/self/io` read (~1 `syscr`, a few
/// hundred `rchar` bytes) inside its own window. Measured as the median
/// of several empty brackets so `count` can subtract it. Page-fault and
/// context-switch fields stay 0 — they carry no steady-state bracket
/// cost, and subtracting sporadic noise would bias real counts.
private (struct) sparkles.test_runner.tier0.Tier0StatsPer-iteration Tier-0 counter deltas of one counting pass. A field is nan
when its source could not be read on this machine.
Tier0Stats sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.calibrateSelfCost() @safeThe per-bracket cost of the bracketing snapshots themselves: each
start/end pair puts one /proc/self/io read (~1 syscr, a few
hundred rchar bytes) inside its own window. Measured as the median
of several empty brackets so count can subtract it. Page-fault and
context-switch fields stay 0 — they carry no steady-state bracket
cost, and subtracting sporadic noise would bias real counts.
calibrateSelfCost() @safe
{
import (package) stdstd.(package) std.algorithmalgorithm.(module) std.algorithm.sortingThis is a submodule of std.algorithm.
It contains generic sorting algorithms.
Function Name Description completeSort If a = [10, 20, 30] and b = [40, 6, 15], then completeSort(a, b) leaves a = [6, 10, 15] and b = [20, 30, 40]. The range a must be sorted prior to the call, and as a result the combination ``chain(a, b) is sorted. isPartitioned isPartitioned!"a < 0"([-1, -2, 1, 0, 2]) returns true because the predicate is true for a portion of the range and false afterwards. isSorted isSorted([1, 1, 2, 3]) returns true. isStrictlyMonotonic isStrictlyMonotonic([1, 1, 2, 3]) returns false. ordered ordered(1, 1, 2, 3) returns true. strictlyOrdered strictlyOrdered(1, 1, 2, 3) returns false. makeIndex Creates a separate index for a range. merge Lazily merges two or more sorted ranges. multiSort Sorts by multiple keys. nextEvenPermutation Computes the next lexicographically greater even permutation of a range in-place. nextPermutation Computes the next lexicographically greater permutation of a range in-place. nthPermutation Computes the nth permutation of a range in-place. partialSort If a = [5, 4, 3, 2, 1], then partialSort(a, 3) leaves a[0 .. 3] = [1, 2, 3]. The other elements of a are left in an unspecified order. partition Partitions a range according to a unary predicate. partition3 Partitions a range according to a binary predicate in three parts (less than, equal, greater than the given pivot). Pivot is not given as an index, but instead as an element independent from the range's content. pivotPartition Partitions a range according to a binary predicate in two parts: less than or equal, and greater than or equal to the given pivot, passed as an index in the range. schwartzSort Sorts with the help of the Schwartzian transform. sort Sorts. topN Separates the top elements in a range, akin to Quickselect. topNCopy Copies out the top elements of a range. topNIndex Builds an index of the top elements of a range.
Source
std/algorithm/sorting.d
sorting : (alias template) sort = std.algorithm.sorting.sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)(Range r)Sorts a random-access range according to the predicate less.
Performs $(BIGOH r.length * log(r.length)) evaluations of `less`. If `less` involves
expensive computations on the _sort key, it may be worthwhile to use
$(LREF schwartzSort) instead.
Stable sorting requires hasAssignableElements!Range to be true.
sort returns a $(REF SortedRange, std,range) over the original range,
allowing functions that can take advantage of sorted data to know that the
range is sorted and adjust accordingly. The $(REF SortedRange, std,range) is a
wrapper around the original range, so both it and the original range are sorted.
Other functions can't know that the original range has been sorted, but
they $(I can) know that $(REF SortedRange, std,range) has been sorted.
Preconditions:
The predicate is expected to satisfy certain rules in order for sort to
behave as expected - otherwise, the program may fail on certain inputs (but not
others) when not compiled in release mode, due to the cursory assumeSorted
check. Specifically, sort expects less(a,b) && less(b,c) to imply
less(a,c) (transitivity), and, conversely, !less(a,b) && !less(b,c) to
imply !less(a,c). Note that the default predicate ("a < b") does not
always satisfy these conditions for floating point types, because the expression
will always be false when either a or b is NaN.
Use $(REF cmp, std,math) instead.
Params:
less = The predicate to sort by.
ss = The swapping strategy to use.
r = The range to sort.
Returns: The initial range wrapped as a SortedRange with the predicate
binaryFun!less.
Algorithms: $(HTTP en.wikipedia.org/wiki/Introsort, Introsort) is used for unstable sorting and
$(HTTP en.wikipedia.org/wiki/Timsort, Timsort) is used for stable sorting.
Each algorithm has benefits beyond stability. Introsort is generally faster but
Timsort may achieve greater speeds on data with low entropy or if predicate calls
are expensive. Introsort performs no allocations whereas Timsort will perform one
or more allocations per call. Both algorithms have $(BIGOH n log n) worst-case
time complexity.
See_Also:
$(REF assumeSorted, std,range)$(BR)
$(REF SortedRange, std,range)$(BR)
$(REF SwapStrategy, std,algorithm,mutation)$(BR)
$(REF binaryFun, std,functional)
sort;
import (package) stdstd.(module) std.mathContains the elementary mathematical functions (powers, roots,
and trigonometric functions), and low-level floating-point operations.
Mathematical special functions are available in std.mathspecial.
Category Members Constants E PI PI_2 PI4 M1_PI M2_PI M2_SQRTPI LN10 LN2 LOG2 LOG2E LOG2T LOG10E SQRT2 SQRT1_2 Algebraic abs fabs sqrt cbrt hypot poly nextPow2 truncPow2 Trigonometry sin cos tan asin acos atan atan2 sinh cosh tanh asinh acosh atanh Rounding ceil floor round lround trunc rint lrint nearbyint rndtol quantize Exponentiation & Logarithms pow powmod exp exp2 expm1 ldexp frexp log log2 log10 logb ilogb log1p scalbn Remainder fmod modf remainder remquo Floating-point operations approxEqual feqrel fdim fmax fmin fma isClose nextDown nextUp nextafter NaN getNaNPayload cmp Introspection isFinite isIdentical isInfinity isNaN isNormal isSubnormal signbit sgn copysign isPowerOf2 Hardware Control IeeeFlags ieeeFlags resetIeeeFlags FloatingPointControl
The functionality closely follows the IEEE754-2008 standard for
floating-point arithmetic, including the use of camelCase names rather
than C99-style lower case names. All of these functions behave correctly
when presented with an infinity or NaN.
The following IEEE 'real' formats are currently supported:
64 bit Big-endian 'double' (eg PowerPC)
128 bit Big-endian 'quadruple' (eg SPARC)
64 bit Little-endian 'double' (eg x86-SSE2)
80 bit Little-endian, with implied bit 'real80' (eg x87, Itanium)
128 bit Little-endian 'quadruple' (not implemented on any known processor!)
Non-IEEE 128 bit Big-endian 'doubledouble' (eg PowerPC) has partial support
Unlike C, there is no global 'errno' variable. Consequently, almost all of
these functions are pure nothrow.
Source
std/math/package.d
math : (alias template) isNaN = std.math.traits.isNaN(X)(X x) if (isFloatingPoint!X)Determines if $(D_PARAM x) is NaN.
Params:
x = a floating point number.
Returns:
`true` if $(D_PARAM x) is Nan.
isNaN;
enum (constant) int sparkles.test_runner.tier0.Tier0Group.calibrateSelfCost.rounds = 9rounds = 9;
double[(constant) int sparkles.test_runner.tier0.Tier0Group.calibrateSelfCost.rounds = 9rounds] (local variable) double[9] syscrsyscr, (local variable) double[9] syscwsyscw, (local variable) double[9] rdCharsrdChars, (local variable) double[9] wrCharswrChars;
foreach ((local variable) int ii; 0 .. (constant) int sparkles.test_runner.tier0.Tier0Group.calibrateSelfCost.rounds = 9rounds)
{
const (local variable) const(sparkles.test_runner.tier0.Tier0Stats) oneone = sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.deltaStats(in sparkles.test_runner.tier0.Tier0Reading a, in sparkles.test_runner.tier0.Tier0Reading b, uint iters) pure nothrow @nogc @safeDivides raw before/after readings into per-iteration Tier0Stats; a source
unavailable in either reading yields nan for its fields.
deltaStats(sparkles.test_runner.tier0.Tier0Reading sparkles.test_runner.tier0.Tier0Group.snapshot() nothrow @nogc @safeReads the cumulative counters now.
snapshot(), sparkles.test_runner.tier0.Tier0Reading sparkles.test_runner.tier0.Tier0Group.snapshot() nothrow @nogc @safeReads the cumulative counters now.
snapshot(), 1);
(local variable) double[9] syscrsyscr[(local variable) int ii] = (local variable) const(sparkles.test_runner.tier0.Tier0Stats) oneone.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr;
(local variable) double[9] syscwsyscw[(local variable) int ii] = (local variable) const(sparkles.test_runner.tier0.Tier0Stats) oneone.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw;
(local variable) double[9] rdCharsrdChars[(local variable) int ii] = (local variable) const(sparkles.test_runner.tier0.Tier0Stats) oneone.(field) double sparkles.test_runner.tier0.Tier0Stats.rdCharsbytes read through the syscall layer (cache included)
rdChars;
(local variable) double[9] wrCharswrChars[(local variable) int ii] = (local variable) const(sparkles.test_runner.tier0.Tier0Stats) oneone.(field) double sparkles.test_runner.tier0.Tier0Stats.wrCharsbytes written through the syscall layer
wrChars;
}
static double double sparkles.test_runner.tier0.Tier0Group.calibrateSelfCost.med(double[] v) pure nothrow @nogc @safemed(double[] (parameter) double[] vv) @safe
{
if ((parameter) double[] vv[0].bool std.math.traits.isNaN!double(double x) pure nothrow @nogc @trustedDetermines if x is NaN.
Examples
assert( isNaN(float.init));
assert( isNaN(-double.init));
assert( isNaN(real.nan));
assert( isNaN(-real.nan));
assert(!isNaN(cast(float) 53.6));
assert(!isNaN(cast(real)-53.6));
isNaN)
return 0; // source unavailable — nothing to subtract
(parameter) double[] vv.std.range.SortedRange!(double[], "a < b", SortedRangeOptions.assumeSorted) std.algorithm.sorting.sort!("a < b", SwapStrategy.unstable, double[])(double[] r) pure nothrow @nogc @safeSorts a random-access range according to the predicate less.
Performs O(r.length * log(r.length)) evaluations of less. If less involves
expensive computations on the sort key, it may be worthwhile to use
schwartzSort instead.
Stable sorting requires hasAssignableElements!Range to be true.
sort returns a SortedRange over the original range,
allowing functions that can take advantage of sorted data to know that the
range is sorted and adjust accordingly. The SortedRange is a
wrapper around the original range, so both it and the original range are sorted.
Other functions can't know that the original range has been sorted, but
they can know that SortedRange has been sorted.
Preconditions
The predicate is expected to satisfy certain rules in order for sort to
behave as expected - otherwise, the program may fail on certain inputs (but not
others) when not compiled in release mode, due to the cursory assumeSorted
check. Specifically, sort expects less(a,b) && less(b,c) to imply
less(a,c) (transitivity), and, conversely, !less(a,b) && !less(b,c) to
imply !less(a,c). Note that the default predicate ("a < b") does not
always satisfy these conditions for floating point types, because the expression
will always be false when either a or b is NaN.
Use cmp instead.
Algorithms
Introsort is used for unstable sorting and
Timsort is used for stable sorting.
Each algorithm has benefits beyond stability. Introsort is generally faster but
Timsort may achieve greater speeds on data with low entropy or if predicate calls
are expensive. Introsort performs no allocations whereas Timsort will perform one
or more allocations per call. Both algorithms have O(n log n) worst-case
time complexity.
Examples
int[] array = [ 1, 2, 3, 4 ];
// sort in descending order
array.sort!("a > b");
assert(array == [ 4, 3, 2, 1 ]);
// sort in ascending order
array.sort();
assert(array == [ 1, 2, 3, 4 ]);
// sort with reusable comparator and chain
alias myComp = (x, y) => x > y;
assert(array.sort!(myComp).release == [ 4, 3, 2, 1 ]);
// Showcase stable sorting
import std.algorithm.mutation : SwapStrategy;
string[] words = [ "aBc", "a", "abc", "b", "ABC", "c" ];
sort!("toUpper(a) < toUpper(b)", SwapStrategy.stable)(words);
assert(words == [ "a", "aBc", "abc", "ABC", "b", "c" ]);
// Sorting floating-point numbers in presence of NaN
double[] numbers = [-0.0, 3.0, -2.0, double.nan, 0.0, -double.nan];
import std.algorithm.comparison : equal;
import std.math.operations : cmp;
import std.math.traits : isIdentical;
sort!((a, b) => cmp(a, b) < 0)(numbers);
double[] sorted = [-double.nan, -2.0, -0.0, 0.0, 3.0, double.nan];
assert(numbers.equal!isIdentical(sorted));
sort;
return (parameter) double[] vv[$ / 2];
}
(struct) sparkles.test_runner.tier0.Tier0StatsPer-iteration Tier-0 counter deltas of one counting pass. A field is nan
when its source could not be read on this machine.
Tier0Stats (local variable) sparkles.test_runner.tier0.Tier0Stats costcost;
(local variable) sparkles.test_runner.tier0.Tier0Stats costcost.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr = double sparkles.test_runner.tier0.Tier0Group.calibrateSelfCost.med(double[] v) pure nothrow @nogc @safemed((local variable) double[9] syscrsyscr[]);
(local variable) sparkles.test_runner.tier0.Tier0Stats costcost.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw = double sparkles.test_runner.tier0.Tier0Group.calibrateSelfCost.med(double[] v) pure nothrow @nogc @safemed((local variable) double[9] syscwsyscw[]);
(local variable) sparkles.test_runner.tier0.Tier0Stats costcost.(field) double sparkles.test_runner.tier0.Tier0Stats.rdCharsbytes read through the syscall layer (cache included)
rdChars = double sparkles.test_runner.tier0.Tier0Group.calibrateSelfCost.med(double[] v) pure nothrow @nogc @safemed((local variable) double[9] rdCharsrdChars[]);
(local variable) sparkles.test_runner.tier0.Tier0Stats costcost.(field) double sparkles.test_runner.tier0.Tier0Stats.wrCharsbytes written through the syscall layer
wrChars = double sparkles.test_runner.tier0.Tier0Group.calibrateSelfCost.med(double[] v) pure nothrow @nogc @safemed((local variable) double[9] wrCharswrChars[]);
return (local variable) sparkles.test_runner.tier0.Tier0Stats costcost;
}
/// Nothing to release; present for surface parity with `PerfGroup`.
void void sparkles.test_runner.tier0.Tier0Group.close() pure nothrow @nogc @safeNothing to release; present for surface parity with PerfGroup.
close() @safe pure nothrow @nogc {}
/// Reads the cumulative counters now.
(struct) sparkles.test_runner.tier0.Tier0ReadingA single instant's raw cumulative counters.
Tier0Reading sparkles.test_runner.tier0.Tier0Reading sparkles.test_runner.tier0.Tier0Group.snapshot() nothrow @nogc @safeReads the cumulative counters now.
snapshot() @safe nothrow @nogc
{
(struct) sparkles.test_runner.tier0.Tier0ReadingA single instant's raw cumulative counters.
Tier0Reading (local variable) sparkles.test_runner.tier0.Tier0Reading rr;
(struct) core.sys.posix.sys.resource.rusagerusage (local variable) core.sys.posix.sys.resource.rusage ruru;
if ((() @trusted => int core.sys.posix.sys.resource.getrusage(int, core.sys.posix.sys.resource.rusage*) nothrow @nogcgetrusage((enum value) core.sys.posix.sys.resource.RUSAGE_SELF = 0RUSAGE_SELF, &(local variable) core.sys.posix.sys.resource.rusage ruru))() == 0)
{
(local variable) sparkles.test_runner.tier0.Tier0Reading rr.(field) long sparkles.test_runner.tier0.Tier0Reading.minfltminflt = (local variable) core.sys.posix.sys.resource.rusage ruru.(field) long core.sys.posix.sys.resource.rusage.ru_minfltru_minflt;
(local variable) sparkles.test_runner.tier0.Tier0Reading rr.(field) long sparkles.test_runner.tier0.Tier0Reading.majfltmajflt = (local variable) core.sys.posix.sys.resource.rusage ruru.(field) long core.sys.posix.sys.resource.rusage.ru_majfltru_majflt;
(local variable) sparkles.test_runner.tier0.Tier0Reading rr.(field) long sparkles.test_runner.tier0.Tier0Reading.volCsvolCs = (local variable) core.sys.posix.sys.resource.rusage ruru.(field) long core.sys.posix.sys.resource.rusage.ru_nvcswru_nvcsw;
(local variable) sparkles.test_runner.tier0.Tier0Reading rr.(field) long sparkles.test_runner.tier0.Tier0Reading.involCsgetrusage
involCs = (local variable) core.sys.posix.sys.resource.rusage ruru.(field) long core.sys.posix.sys.resource.rusage.ru_nivcswru_nivcsw;
(local variable) sparkles.test_runner.tier0.Tier0Reading rr.(field) bool sparkles.test_runner.tier0.Tier0Reading.rusageOkrusageOk = true;
}
char[1024] (local variable) char[1024] bufbuf = void;
const (local variable) const(char[]) ioio = char[] sparkles.test_runner.tier0.readProcSelfIo(return scope char[] buf) nothrow @nogc @safeReads /proc/self/io into buf via a raw open/read/close; returns
the filled slice (empty on failure). std.file reports size 0 for /proc,
so a direct read is required.
readProcSelfIo((local variable) char[1024] bufbuf[]);
if ((local variable) const(char[]) ioio.(field) ulong const(char[]).lengthlength)
{
(local variable) sparkles.test_runner.tier0.Tier0Reading rr.(field) long sparkles.test_runner.tier0.Tier0Reading.syscrsyscr = long sparkles.test_runner.tier0.parseProcField(const(char)[] content, const(char)[] key) pure nothrow @nogc @safeFinds key`:` at a line start in a `/proc`-style key:\tvalue file and parses
the trailing unsigned integer; -1 when the key is absent or unparsable.
parseProcField((local variable) const(char[]) ioio, "syscr");
(local variable) sparkles.test_runner.tier0.Tier0Reading rr.(field) long sparkles.test_runner.tier0.Tier0Reading.syscwsyscw = long sparkles.test_runner.tier0.parseProcField(const(char)[] content, const(char)[] key) pure nothrow @nogc @safeFinds key`:` at a line start in a `/proc`-style key:\tvalue file and parses
the trailing unsigned integer; -1 when the key is absent or unparsable.
parseProcField((local variable) const(char[]) ioio, "syscw");
(local variable) sparkles.test_runner.tier0.Tier0Reading rr.(field) long sparkles.test_runner.tier0.Tier0Reading.rdCharsrdChars = long sparkles.test_runner.tier0.parseProcField(const(char)[] content, const(char)[] key) pure nothrow @nogc @safeFinds key`:` at a line start in a `/proc`-style key:\tvalue file and parses
the trailing unsigned integer; -1 when the key is absent or unparsable.
parseProcField((local variable) const(char[]) ioio, "rchar");
(local variable) sparkles.test_runner.tier0.Tier0Reading rr.(field) long sparkles.test_runner.tier0.Tier0Reading.wrCharswrChars = long sparkles.test_runner.tier0.parseProcField(const(char)[] content, const(char)[] key) pure nothrow @nogc @safeFinds key`:` at a line start in a `/proc`-style key:\tvalue file and parses
the trailing unsigned integer; -1 when the key is absent or unparsable.
parseProcField((local variable) const(char[]) ioio, "wchar");
(local variable) sparkles.test_runner.tier0.Tier0Reading rr.(field) long sparkles.test_runner.tier0.Tier0Reading.rdBytesrdBytes = long sparkles.test_runner.tier0.parseProcField(const(char)[] content, const(char)[] key) pure nothrow @nogc @safeFinds key`:` at a line start in a `/proc`-style key:\tvalue file and parses
the trailing unsigned integer; -1 when the key is absent or unparsable.
parseProcField((local variable) const(char[]) ioio, "read_bytes");
(local variable) sparkles.test_runner.tier0.Tier0Reading rr.(field) long sparkles.test_runner.tier0.Tier0Reading.wrBytes/proc/self/io
wrBytes = long sparkles.test_runner.tier0.parseProcField(const(char)[] content, const(char)[] key) pure nothrow @nogc @safeFinds key`:` at a line start in a `/proc`-style key:\tvalue file and parses
the trailing unsigned integer; -1 when the key is absent or unparsable.
parseProcField((local variable) const(char[]) ioio, "write_bytes");
// A field the kernel omits (older kernels, restricted) reads -1;
// treat the source as usable iff the always-present counts are.
(local variable) sparkles.test_runner.tier0.Tier0Reading rr.(field) bool sparkles.test_runner.tier0.Tier0Reading.ioOkioOk = (local variable) sparkles.test_runner.tier0.Tier0Reading rr.(field) long sparkles.test_runner.tier0.Tier0Reading.syscrsyscr >= 0 && (local variable) sparkles.test_runner.tier0.Tier0Reading rr.(field) long sparkles.test_runner.tier0.Tier0Reading.rdCharsrdChars >= 0;
}
return (local variable) sparkles.test_runner.tier0.Tier0Reading rr;
}
/// The counting pass: brackets each `timed()` call with its own pair of
/// snapshots so `between()` runs outside the counted window, sums the
/// per-call deltas, and averages once. Returns per-iteration deltas; an
/// unavailable source reads `nan` (it propagates through the sum).
/// `batch` brackets that many iterations per snapshot pair, so the two
/// `/proc` reads amortize instead of dominating a fast body (the tier-0
/// analogue of the perf bracket's ioctl cost). Only sound when
/// `between` is a no-op — the batched rows — so per-call rows keep
/// `batch == 1`, where this is the original per-iteration loop.
(struct) sparkles.test_runner.tier0.Tier0StatsPer-iteration Tier-0 counter deltas of one counting pass. A field is nan
when its source could not be read on this machine.
Tier0Stats sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.count!(void function() pure nothrow @nogc @safe, void function() nothrow @nogc @safe)(scope void function() pure nothrow @nogc @safe timed, scope void function() nothrow @nogc @safe between, uint iters, uint batch = 1u) nothrow @nogc @safeThe counting pass: brackets each timed`()` call with its own pair of
snapshots so between() runs outside the counted window, sums the
per-call deltas, and averages once. Returns per-iteration deltas; an
unavailable source reads nan (it propagates through the sum).
batch brackets that many iterations per snapshot pair, so the two
/proc reads amortize instead of dominating a fast body (the tier-0
analogue of the perf bracket's ioctl cost). Only sound when
between is a no-op — the batched rows — so per-call rows keep
``batch == 1, where this is the original per-iteration loop.
count(Timed, Between)(scope (alias) Timed = void function() pure nothrow @nogc @safeTimed (parameter) void function() pure nothrow @nogc @safe timedtimed, scope (alias) Between = void function() nothrow @nogc @safeBetween (parameter) void function() nothrow @nogc @safe betweenbetween,
uint (parameter) uint itersiters, uint (parameter) uint batchbatch = 1)
in ((parameter) uint itersiters > 0)
{
(struct) sparkles.test_runner.tier0.Tier0StatsPer-iteration Tier-0 counter deltas of one counting pass. A field is nan
when its source could not be read on this machine.
Tier0Stats (local variable) sparkles.test_runner.tier0.Tier0Stats sumsum; // running sum of raw deltas (nan propagates)
const (local variable) const(uint) kk = (parameter) uint batchbatch == 0 ? 1 : (parameter) uint batchbatch;
uint (local variable) uint donedone, (local variable) uint bracketsbrackets;
while ((local variable) uint donedone < (parameter) uint itersiters)
{
const (local variable) const(uint) nn = (local variable) const(uint) kk < (parameter) uint itersiters - (local variable) uint donedone ? (local variable) const(uint) kk : (parameter) uint itersiters - (local variable) uint donedone;
(local variable) uint donedone += (local variable) const(uint) nn;
++(local variable) uint bracketsbrackets;
const (local variable) const(sparkles.test_runner.tier0.Tier0Reading) startstart = sparkles.test_runner.tier0.Tier0Reading sparkles.test_runner.tier0.Tier0Group.snapshot() nothrow @nogc @safeReads the cumulative counters now.
snapshot();
foreach ((local variable) uint __; 0 .. (local variable) const(uint) nn)
(parameter) void function() pure nothrow @nogc @safe timedtimed();
const (local variable) const(sparkles.test_runner.tier0.Tier0Reading) endend = sparkles.test_runner.tier0.Tier0Reading sparkles.test_runner.tier0.Tier0Group.snapshot() nothrow @nogc @safeReads the cumulative counters now.
snapshot();
foreach ((local variable) uint __; 0 .. (local variable) const(uint) nn)
(parameter) void function() nothrow @nogc @safe betweenbetween(); // untimed teardown, outside the start..end window
// Raw (divisor 1): `sum` accumulates the whole pass's counts,
// which the `1/iters` below turns into a per-iteration average
// — correct for any batch size.
const (local variable) const(sparkles.test_runner.tier0.Tier0Stats) oneone = sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.deltaStats(in sparkles.test_runner.tier0.Tier0Reading a, in sparkles.test_runner.tier0.Tier0Reading b, uint iters) pure nothrow @nogc @safeDivides raw before/after readings into per-iteration Tier0Stats; a source
unavailable in either reading yields nan for its fields.
deltaStats((local variable) const(sparkles.test_runner.tier0.Tier0Reading) startstart, (local variable) const(sparkles.test_runner.tier0.Tier0Reading) endend, 1);
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.minfltminor page faults per iteration (getrusage)
minflt += (local variable) const(sparkles.test_runner.tier0.Tier0Stats) oneone.(field) double sparkles.test_runner.tier0.Tier0Stats.minfltminor page faults per iteration (getrusage)
minflt;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.majfltmajor page faults per iteration (getrusage)
majflt += (local variable) const(sparkles.test_runner.tier0.Tier0Stats) oneone.(field) double sparkles.test_runner.tier0.Tier0Stats.majfltmajor page faults per iteration (getrusage)
majflt;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.volCsvoluntary context switches per iteration (blocked on I/O)
volCs += (local variable) const(sparkles.test_runner.tier0.Tier0Stats) oneone.(field) double sparkles.test_runner.tier0.Tier0Stats.volCsvoluntary context switches per iteration (blocked on I/O)
volCs;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.involCsinvoluntary context switches per iteration (preempted)
involCs += (local variable) const(sparkles.test_runner.tier0.Tier0Stats) oneone.(field) double sparkles.test_runner.tier0.Tier0Stats.involCsinvoluntary context switches per iteration (preempted)
involCs;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr += (local variable) const(sparkles.test_runner.tier0.Tier0Stats) oneone.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw += (local variable) const(sparkles.test_runner.tier0.Tier0Stats) oneone.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.rdCharsbytes read through the syscall layer (cache included)
rdChars += (local variable) const(sparkles.test_runner.tier0.Tier0Stats) oneone.(field) double sparkles.test_runner.tier0.Tier0Stats.rdCharsbytes read through the syscall layer (cache included)
rdChars;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.wrCharsbytes written through the syscall layer
wrChars += (local variable) const(sparkles.test_runner.tier0.Tier0Stats) oneone.(field) double sparkles.test_runner.tier0.Tier0Stats.wrCharsbytes written through the syscall layer
wrChars;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.rdBytesbytes that actually hit the block device (reads)
rdBytes += (local variable) const(sparkles.test_runner.tier0.Tier0Stats) oneone.(field) double sparkles.test_runner.tier0.Tier0Stats.rdBytesbytes that actually hit the block device (reads)
rdBytes;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.wrBytesbytes that actually hit the block device (writes)
wrBytes += (local variable) const(sparkles.test_runner.tier0.Tier0Stats) oneone.(field) double sparkles.test_runner.tier0.Tier0Stats.wrBytesbytes that actually hit the block device (writes)
wrBytes;
}
const (local variable) const(double) invinv = 1.0 / (parameter) uint itersiters;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) ulong sparkles.test_runner.tier0.Tier0Stats.iterscounting-pass iterations
iters = (parameter) uint itersiters;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.minfltminor page faults per iteration (getrusage)
minflt *= (local variable) const(double) invinv;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.majfltmajor page faults per iteration (getrusage)
majflt *= (local variable) const(double) invinv;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.volCsvoluntary context switches per iteration (blocked on I/O)
volCs *= (local variable) const(double) invinv;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.involCsinvoluntary context switches per iteration (preempted)
involCs *= (local variable) const(double) invinv;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr *= (local variable) const(double) invinv;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw *= (local variable) const(double) invinv;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.rdCharsbytes read through the syscall layer (cache included)
rdChars *= (local variable) const(double) invinv;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.wrCharsbytes written through the syscall layer
wrChars *= (local variable) const(double) invinv;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.rdBytesbytes that actually hit the block device (reads)
rdBytes *= (local variable) const(double) invinv;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.wrBytesbytes that actually hit the block device (writes)
wrBytes *= (local variable) const(double) invinv;
// Net of the brackets' own snapshot cost (calibrated at open):
// without this a no-I/O body reads ~1 syscr and a few hundred
// rchar bytes per iteration, and `cacheHitPercent`'s "nothing was
// read → nan" branch is unreachable (rchar always > 0).
//
// The calibration is the cost of ONE bracket, and `sum` is now
// per-iteration — so the amount to remove is one bracket's cost
// spread over the iterations it covered. At `batch == 1` that is
// `brackets == iters` and the factor is 1 (the original behaviour);
// batching lowers it, because a batched pass really does pay the
// snapshot cost fewer times.
const (local variable) const(double) costSharecostShare = double((local variable) uint bracketsbrackets) / (parameter) uint itersiters;
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr = double sparkles.test_runner.tier0.netOfCost(double total, double cost) pure nothrow @nogc @safeA counter net of its calibrated per-bracket cost, clamped at zero;
nan (source unavailable) passes through untouched. Platform-neutral:
the darwin perf body (proc_pid_rusage fixed counters) nets its bracket
cost through the same helper.
netOfCost((local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr, (field) sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.selfCostper-bracket snapshot cost; 0 = uncalibrated
selfCost.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr * (local variable) const(double) costSharecostShare);
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw = double sparkles.test_runner.tier0.netOfCost(double total, double cost) pure nothrow @nogc @safeA counter net of its calibrated per-bracket cost, clamped at zero;
nan (source unavailable) passes through untouched. Platform-neutral:
the darwin perf body (proc_pid_rusage fixed counters) nets its bracket
cost through the same helper.
netOfCost((local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw, (field) sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.selfCostper-bracket snapshot cost; 0 = uncalibrated
selfCost.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw * (local variable) const(double) costSharecostShare);
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.rdCharsbytes read through the syscall layer (cache included)
rdChars = double sparkles.test_runner.tier0.netOfCost(double total, double cost) pure nothrow @nogc @safeA counter net of its calibrated per-bracket cost, clamped at zero;
nan (source unavailable) passes through untouched. Platform-neutral:
the darwin perf body (proc_pid_rusage fixed counters) nets its bracket
cost through the same helper.
netOfCost((local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.rdCharsbytes read through the syscall layer (cache included)
rdChars, (field) sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.selfCostper-bracket snapshot cost; 0 = uncalibrated
selfCost.(field) double sparkles.test_runner.tier0.Tier0Stats.rdCharsbytes read through the syscall layer (cache included)
rdChars * (local variable) const(double) costSharecostShare);
(local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.wrCharsbytes written through the syscall layer
wrChars = double sparkles.test_runner.tier0.netOfCost(double total, double cost) pure nothrow @nogc @safeA counter net of its calibrated per-bracket cost, clamped at zero;
nan (source unavailable) passes through untouched. Platform-neutral:
the darwin perf body (proc_pid_rusage fixed counters) nets its bracket
cost through the same helper.
netOfCost((local variable) sparkles.test_runner.tier0.Tier0Stats sumsum.(field) double sparkles.test_runner.tier0.Tier0Stats.wrCharsbytes written through the syscall layer
wrChars, (field) sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.selfCostper-bracket snapshot cost; 0 = uncalibrated
selfCost.(field) double sparkles.test_runner.tier0.Tier0Stats.wrCharsbytes written through the syscall layer
wrChars * (local variable) const(double) costSharecostShare);
return (local variable) sparkles.test_runner.tier0.Tier0Stats sumsum;
}
/// The tier-0 deltas across one window, as window $(B totals)
/// (`iters = 1`), net of a single bracket's calibrated snapshot cost.
(struct) sparkles.test_runner.tier0.Tier0StatsPer-iteration Tier-0 counter deltas of one counting pass. A field is nan
when its source could not be read on this machine.
Tier0Stats sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.windowStats(in sparkles.test_runner.tier0.Tier0Reading a, in sparkles.test_runner.tier0.Tier0Reading b) const pure nothrow @nogc @safeThe tier-0 deltas across one window, as window totals
(iters = 1), net of a single bracket's calibrated snapshot cost.
windowStats(in (struct) sparkles.test_runner.tier0.Tier0ReadingA single instant's raw cumulative counters.
Tier0Reading (parameter) const(sparkles.test_runner.tier0.Tier0Reading) aa, in (struct) sparkles.test_runner.tier0.Tier0ReadingA single instant's raw cumulative counters.
Tier0Reading (parameter) const(sparkles.test_runner.tier0.Tier0Reading) bb)
const @safe pure nothrow @nogc
{
auto (local variable) sparkles.test_runner.tier0.Tier0Stats ss = sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.deltaStats(in sparkles.test_runner.tier0.Tier0Reading a, in sparkles.test_runner.tier0.Tier0Reading b, uint iters) pure nothrow @nogc @safeDivides raw before/after readings into per-iteration Tier0Stats; a source
unavailable in either reading yields nan for its fields.
deltaStats((parameter) const(sparkles.test_runner.tier0.Tier0Reading) aa, (parameter) const(sparkles.test_runner.tier0.Tier0Reading) bb, 1);
(local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr = double sparkles.test_runner.tier0.netOfCost(double total, double cost) pure nothrow @nogc @safeA counter net of its calibrated per-bracket cost, clamped at zero;
nan (source unavailable) passes through untouched. Platform-neutral:
the darwin perf body (proc_pid_rusage fixed counters) nets its bracket
cost through the same helper.
netOfCost((local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr, (field) sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.selfCostper-bracket snapshot cost; 0 = uncalibrated
selfCost.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr);
(local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw = double sparkles.test_runner.tier0.netOfCost(double total, double cost) pure nothrow @nogc @safeA counter net of its calibrated per-bracket cost, clamped at zero;
nan (source unavailable) passes through untouched. Platform-neutral:
the darwin perf body (proc_pid_rusage fixed counters) nets its bracket
cost through the same helper.
netOfCost((local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw, (field) sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.selfCostper-bracket snapshot cost; 0 = uncalibrated
selfCost.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw);
(local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.rdCharsbytes read through the syscall layer (cache included)
rdChars = double sparkles.test_runner.tier0.netOfCost(double total, double cost) pure nothrow @nogc @safeA counter net of its calibrated per-bracket cost, clamped at zero;
nan (source unavailable) passes through untouched. Platform-neutral:
the darwin perf body (proc_pid_rusage fixed counters) nets its bracket
cost through the same helper.
netOfCost((local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.rdCharsbytes read through the syscall layer (cache included)
rdChars, (field) sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.selfCostper-bracket snapshot cost; 0 = uncalibrated
selfCost.(field) double sparkles.test_runner.tier0.Tier0Stats.rdCharsbytes read through the syscall layer (cache included)
rdChars);
(local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.wrCharsbytes written through the syscall layer
wrChars = double sparkles.test_runner.tier0.netOfCost(double total, double cost) pure nothrow @nogc @safeA counter net of its calibrated per-bracket cost, clamped at zero;
nan (source unavailable) passes through untouched. Platform-neutral:
the darwin perf body (proc_pid_rusage fixed counters) nets its bracket
cost through the same helper.
netOfCost((local variable) sparkles.test_runner.tier0.Tier0Stats ss.(field) double sparkles.test_runner.tier0.Tier0Stats.wrCharsbytes written through the syscall layer
wrChars, (field) sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.selfCostper-bracket snapshot cost; 0 = uncalibrated
selfCost.(field) double sparkles.test_runner.tier0.Tier0Stats.wrCharsbytes written through the syscall layer
wrChars);
return (local variable) sparkles.test_runner.tier0.Tier0Stats ss;
}
}
/// Reads `/proc/self/io` into `buf` via a raw `open`/`read`/`close`; returns
/// the filled slice (empty on failure). `std.file` reports size 0 for `/proc`,
/// so a direct read is required.
private char[] char[] sparkles.test_runner.tier0.readProcSelfIo(return scope char[] buf) nothrow @nogc @safeReads /proc/self/io into buf via a raw open/read/close; returns
the filled slice (empty on failure). std.file reports size 0 for /proc,
so a direct read is required.
readProcSelfIo(return scope char[] (parameter) char[] bufbuf) @safe nothrow @nogc
{
import (package) corecore.(package) core.syssys.(package) core.sys.posixposix.(module) core.sys.posix.fcntlD header file for POSIX.
fcntl : open, (alias constant) O_RDONLY = int core.sys.posix.fcntl.O_RDONLY = 0O_RDONLY;
import (package) corecore.(package) core.syssys.(package) core.sys.posixposix.(module) core.sys.posix.unistdD header file for POSIX.
unistd : (alias) read = long core.sys.posix.unistd.read(int, void*, ulong) nothrow @nogcread, (alias) close = int core.sys.posix.unistd.close(int) nothrow @nogc @trustedclose;
const (local variable) const(int) fdfd = (() @trusted => open("/proc/self/io", (constant) int core.sys.posix.fcntl.O_RDONLY = 0O_RDONLY))();
if ((local variable) const(int) fdfd < 0)
return null;
scope (exit)
(() @trusted => int core.sys.posix.unistd.close(int) nothrow @nogc @trustedclose((local variable) const(int) fdfd))();
const (local variable) const(long) nn = (() @trusted => long core.sys.posix.unistd.read(int, void*, ulong) nothrow @nogcread((local variable) const(int) fdfd, (parameter) char[] bufbuf.(field) char* char[].ptrptr, (parameter) char[] bufbuf.(field) ulong char[].lengthlength))();
return (local variable) const(long) nn > 0 ? (parameter) char[] bufbuf[0 .. (local variable) const(long) nn] : null;
}
@("tier0.Tier0Group.countSmoke")
@system
unittest
{
auto (local variable) sparkles.test_runner.tier0.Tier0Group gg = (struct) sparkles.test_runner.tier0.Tier0GroupThe Tier-0 counter group. No fds; count snapshots the cumulative
counters around each iteration. Carries the calibrated per-bracket
self-cost of the snapshots themselves (see calibrateSelfCost).
Tier0Group.sparkles.test_runner.tier0.Tier0Group sparkles.test_runner.tier0.Tier0Group.tryOpen(bool enabled) @safeEnables collection when enabled and calibrates the snapshot
self-cost; otherwise an unavailable group (mirrors
PerfGroup.tryOpen(false)), so the same call sites work.
tryOpen(true);
assert((local variable) sparkles.test_runner.tier0.Tier0Group gg.bool sparkles.test_runner.tier0.Tier0Group.available() const pure nothrow @nogc @safeWhether Tier-0 counters will be collected (Linux and requested).
available);
// A body that forces at least one write syscall so a count is observable.
static void void sparkles.test_runner.tier0.__unittest_L411_C5.body_() nothrow @nogc @safebody_()
{
import (package) corecore.(package) core.syssys.(package) core.sys.posixposix.(module) core.sys.posix.unistdD header file for POSIX.
unistd : (alias) write = long core.sys.posix.unistd.write(int, scope const(void*), ulong) nothrow @nogcwrite;
char[1] (local variable) char[1] cc = ['x'];
() @trusted { long core.sys.posix.unistd.write(int, scope const(void*), ulong) nothrow @nogcwrite(2, (local variable) char[1] cc.(constant) char* char[1].ptr = &cptr, 0); }(); // 0-length write to stderr: a syscall, no output
}
const (local variable) const(sparkles.test_runner.tier0.Tier0Stats) ss = (local variable) sparkles.test_runner.tier0.Tier0Group gg.sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.count!(void function() nothrow @nogc @safe, void function() pure nothrow @nogc @safe)(scope void function() nothrow @nogc @safe timed, scope void function() pure nothrow @nogc @safe between, uint iters, uint batch = 1u) nothrow @nogc @safeThe counting pass: brackets each timed`()` call with its own pair of
snapshots so between() runs outside the counted window, sums the
per-call deltas, and averages once. Returns per-iteration deltas; an
unavailable source reads nan (it propagates through the sum).
batch brackets that many iterations per snapshot pair, so the two
/proc reads amortize instead of dominating a fast body (the tier-0
analogue of the perf bracket's ioctl cost). Only sound when
between is a no-op — the batched rows — so per-call rows keep
``batch == 1, where this is the original per-iteration loop.
count(&void sparkles.test_runner.tier0.__unittest_L411_C5.body_() nothrow @nogc @safebody_, () {}, 64);
assert((local variable) const(sparkles.test_runner.tier0.Tier0Stats) ss.(field) ulong sparkles.test_runner.tier0.Tier0Stats.iterscounting-pass iterations
iters == 64);
import (package) stdstd.(module) std.mathContains the elementary mathematical functions (powers, roots,
and trigonometric functions), and low-level floating-point operations.
Mathematical special functions are available in std.mathspecial.
Category Members Constants E PI PI_2 PI4 M1_PI M2_PI M2_SQRTPI LN10 LN2 LOG2 LOG2E LOG2T LOG10E SQRT2 SQRT1_2 Algebraic abs fabs sqrt cbrt hypot poly nextPow2 truncPow2 Trigonometry sin cos tan asin acos atan atan2 sinh cosh tanh asinh acosh atanh Rounding ceil floor round lround trunc rint lrint nearbyint rndtol quantize Exponentiation & Logarithms pow powmod exp exp2 expm1 ldexp frexp log log2 log10 logb ilogb log1p scalbn Remainder fmod modf remainder remquo Floating-point operations approxEqual feqrel fdim fmax fmin fma isClose nextDown nextUp nextafter NaN getNaNPayload cmp Introspection isFinite isIdentical isInfinity isNaN isNormal isSubnormal signbit sgn copysign isPowerOf2 Hardware Control IeeeFlags ieeeFlags resetIeeeFlags FloatingPointControl
The functionality closely follows the IEEE754-2008 standard for
floating-point arithmetic, including the use of camelCase names rather
than C99-style lower case names. All of these functions behave correctly
when presented with an infinity or NaN.
The following IEEE 'real' formats are currently supported:
64 bit Big-endian 'double' (eg PowerPC)
128 bit Big-endian 'quadruple' (eg SPARC)
64 bit Little-endian 'double' (eg x86-SSE2)
80 bit Little-endian, with implied bit 'real80' (eg x87, Itanium)
128 bit Little-endian 'quadruple' (not implemented on any known processor!)
Non-IEEE 128 bit Big-endian 'doubledouble' (eg PowerPC) has partial support
Unlike C, there is no global 'errno' variable. Consequently, almost all of
these functions are pure nothrow.
Source
std/math/package.d
math : (alias template) isNaN = std.math.traits.isNaN(X)(X x) if (isFloatingPoint!X)Determines if $(D_PARAM x) is NaN.
Params:
x = a floating point number.
Returns:
`true` if $(D_PARAM x) is Nan.
isNaN;
// On a normal Linux host both sources read; syscall count is non-negative.
if (!(local variable) const(sparkles.test_runner.tier0.Tier0Stats) ss.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw.bool std.math.traits.isNaN!(const(double))(const(double) x) pure nothrow @nogc @trustedDetermines if x is NaN.
Examples
assert( isNaN(float.init));
assert( isNaN(-double.init));
assert( isNaN(real.nan));
assert( isNaN(-real.nan));
assert(!isNaN(cast(float) 53.6));
assert(!isNaN(cast(real)-53.6));
isNaN)
assert((local variable) const(sparkles.test_runner.tier0.Tier0Stats) ss.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw >= 0);
}
@("tier0.Tier0Group.countExcludesBetween")
@system
unittest
{
import (package) stdstd.(module) std.convA one-stop shop for converting values from one type to another.
Category Functions Generic asOriginalType castFrom parse to toChars bitCast Strings text wtext dtext writeText writeWText writeDText hexString Numeric octal roundTo signed unsigned Exceptions ConvException ConvOverflowException
Source
std/conv.d
conv : (alias template) text = std.conv.text(T...)(T args) if (T.length > 0)Convenience functions for converting one or more arguments
of any type into _text (the three character widths).
text;
import (package) stdstd.(module) std.mathContains the elementary mathematical functions (powers, roots,
and trigonometric functions), and low-level floating-point operations.
Mathematical special functions are available in std.mathspecial.
Category Members Constants E PI PI_2 PI4 M1_PI M2_PI M2_SQRTPI LN10 LN2 LOG2 LOG2E LOG2T LOG10E SQRT2 SQRT1_2 Algebraic abs fabs sqrt cbrt hypot poly nextPow2 truncPow2 Trigonometry sin cos tan asin acos atan atan2 sinh cosh tanh asinh acosh atanh Rounding ceil floor round lround trunc rint lrint nearbyint rndtol quantize Exponentiation & Logarithms pow powmod exp exp2 expm1 ldexp frexp log log2 log10 logb ilogb log1p scalbn Remainder fmod modf remainder remquo Floating-point operations approxEqual feqrel fdim fmax fmin fma isClose nextDown nextUp nextafter NaN getNaNPayload cmp Introspection isFinite isIdentical isInfinity isNaN isNormal isSubnormal signbit sgn copysign isPowerOf2 Hardware Control IeeeFlags ieeeFlags resetIeeeFlags FloatingPointControl
The functionality closely follows the IEEE754-2008 standard for
floating-point arithmetic, including the use of camelCase names rather
than C99-style lower case names. All of these functions behave correctly
when presented with an infinity or NaN.
The following IEEE 'real' formats are currently supported:
64 bit Big-endian 'double' (eg PowerPC)
128 bit Big-endian 'quadruple' (eg SPARC)
64 bit Little-endian 'double' (eg x86-SSE2)
80 bit Little-endian, with implied bit 'real80' (eg x87, Itanium)
128 bit Little-endian 'quadruple' (not implemented on any known processor!)
Non-IEEE 128 bit Big-endian 'doubledouble' (eg PowerPC) has partial support
Unlike C, there is no global 'errno' variable. Consequently, almost all of
these functions are pure nothrow.
Source
std/math/package.d
math : (alias template) isNaN = std.math.traits.isNaN(X)(X x) if (isFloatingPoint!X)Determines if $(D_PARAM x) is NaN.
Params:
x = a floating point number.
Returns:
`true` if $(D_PARAM x) is Nan.
isNaN;
// Per-iteration bracketing must exclude the untimed `between` from the
// window. The same writes count when they run as `timed` but not as
// `between`. Compare the two so process-wide noise from concurrent test
// threads (getrusage/proc are per-process) drops out of the DIFFERENCE
// only on average — the two count() passes run sequentially, so the
// signal (32 writes/iter) is sized to dwarf any realistic burst of
// cross-thread write syscalls rather than merely exceed it.
import (package) sparklessparkles.(package) sparkles.test_runnertest_runner.(module) sparkles.test_runner.skipFirst-class test skipping: skipTest("reason") aborts the current test and
the runner records it as SKIPPED — a yellow ⊘ result line with the reason
and an N skipped summary segment — instead of the early-return pattern
that silently counts a degraded environment as a pass.
Runtime-only: not usable in @ctfe bodies (the probe compile evaluates
them, and a skip there is a compile error) nor in the extracted
--better-c/--wasm programs (no druntime classes there). Inside a
@benchmark body, prefer skipping at registration time (the top of the
body) — a skipTest inside a deferred benchIter/benchCase closure
skips only that case's row.
skip : (alias) skipTest = noreturn sparkles.test_runner.skip.skipTest(string reason) pure nothrow @nogc @safeAborts the current test, recording it as skipped with reason — for
environment capabilities a test needs but this machine/run lacks (perf
counters, a root-only tracefs, a missing toolchain binary). Callable from
the strictest test bodies: throwing an Error is nothrow-legal, and the
recycled instance keeps it @nogc (the minimal @trusted covers only the
deliberately-@system recycledErrorInstance).
skipTest;
auto (local variable) sparkles.test_runner.tier0.Tier0Group gg = (struct) sparkles.test_runner.tier0.Tier0GroupThe Tier-0 counter group. No fds; count snapshots the cumulative
counters around each iteration. Carries the calibrated per-bracket
self-cost of the snapshots themselves (see calibrateSelfCost).
Tier0Group.sparkles.test_runner.tier0.Tier0Group sparkles.test_runner.tier0.Tier0Group.tryOpen(bool enabled) @safeEnables collection when enabled and calibrates the snapshot
self-cost; otherwise an unavailable group (mirrors
PerfGroup.tryOpen(false)), so the same call sites work.
tryOpen(true);
if (!(local variable) sparkles.test_runner.tier0.Tier0Group gg.bool sparkles.test_runner.tier0.Tier0Group.available() const pure nothrow @nogc @safeWhether Tier-0 counters will be collected (Linux and requested).
available)
noreturn sparkles.test_runner.skip.skipTest(string reason) pure nothrow @nogc @safeAborts the current test, recording it as skipped with reason — for
environment capabilities a test needs but this machine/run lacks (perf
counters, a root-only tracefs, a missing toolchain binary). Callable from
the strictest test bodies: throwing an Error is nothrow-legal, and the
recycled instance keeps it @nogc (the minimal @trusted covers only the
deliberately-@system recycledErrorInstance).
skipTest("tier-0 counters unavailable");
static void void sparkles.test_runner.tier0.__unittest_L434_C5.nop() pure nothrow @nogc @safenop() {}
static void void sparkles.test_runner.tier0.__unittest_L434_C5.writeBurst() nothrow @nogc @safewriteBurst()
{
import (package) corecore.(package) core.syssys.(package) core.sys.posixposix.(module) core.sys.posix.unistdD header file for POSIX.
unistd : (alias) write = long core.sys.posix.unistd.write(int, scope const(void*), ulong) nothrow @nogcwrite;
char[1] (local variable) char[1] cc = ['x'];
foreach ((local variable) int __; 0 .. 32) // 0-length writes: syscalls, no output
() @trusted { long core.sys.posix.unistd.write(int, scope const(void*), ulong) nothrow @nogcwrite(2, (local variable) char[1] cc.(constant) char* char[1].ptr = &cptr, 0); }();
}
const (local variable) const(sparkles.test_runner.tier0.Tier0Stats) inTimedinTimed = (local variable) sparkles.test_runner.tier0.Tier0Group gg.sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.count!(void function() nothrow @nogc @safe, void function() pure nothrow @nogc @safe)(scope void function() nothrow @nogc @safe timed, scope void function() pure nothrow @nogc @safe between, uint iters, uint batch = 1u) nothrow @nogc @safeThe counting pass: brackets each timed`()` call with its own pair of
snapshots so between() runs outside the counted window, sums the
per-call deltas, and averages once. Returns per-iteration deltas; an
unavailable source reads nan (it propagates through the sum).
batch brackets that many iterations per snapshot pair, so the two
/proc reads amortize instead of dominating a fast body (the tier-0
analogue of the perf bracket's ioctl cost). Only sound when
between is a no-op — the batched rows — so per-call rows keep
``batch == 1, where this is the original per-iteration loop.
count(&void sparkles.test_runner.tier0.__unittest_L434_C5.writeBurst() nothrow @nogc @safewriteBurst, &void sparkles.test_runner.tier0.__unittest_L434_C5.nop() pure nothrow @nogc @safenop, 64); // writes inside the window
const (local variable) const(sparkles.test_runner.tier0.Tier0Stats) inBetweeninBetween = (local variable) sparkles.test_runner.tier0.Tier0Group gg.sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.count!(void function() pure nothrow @nogc @safe, void function() nothrow @nogc @safe)(scope void function() pure nothrow @nogc @safe timed, scope void function() nothrow @nogc @safe between, uint iters, uint batch = 1u) nothrow @nogc @safeThe counting pass: brackets each timed`()` call with its own pair of
snapshots so between() runs outside the counted window, sums the
per-call deltas, and averages once. Returns per-iteration deltas; an
unavailable source reads nan (it propagates through the sum).
batch brackets that many iterations per snapshot pair, so the two
/proc reads amortize instead of dominating a fast body (the tier-0
analogue of the perf bracket's ioctl cost). Only sound when
between is a no-op — the batched rows — so per-call rows keep
``batch == 1, where this is the original per-iteration loop.
count(&void sparkles.test_runner.tier0.__unittest_L434_C5.nop() pure nothrow @nogc @safenop, &void sparkles.test_runner.tier0.__unittest_L434_C5.writeBurst() nothrow @nogc @safewriteBurst, 64); // writes outside the window
if (!(local variable) const(sparkles.test_runner.tier0.Tier0Stats) inTimedinTimed.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw.bool std.math.traits.isNaN!(const(double))(const(double) x) pure nothrow @nogc @trustedDetermines if x is NaN.
Examples
assert( isNaN(float.init));
assert( isNaN(-double.init));
assert( isNaN(real.nan));
assert( isNaN(-real.nan));
assert(!isNaN(cast(float) 53.6));
assert(!isNaN(cast(real)-53.6));
isNaN && !(local variable) const(sparkles.test_runner.tier0.Tier0Stats) inBetweeninBetween.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw.bool std.math.traits.isNaN!(const(double))(const(double) x) pure nothrow @nogc @trustedDetermines if x is NaN.
Examples
assert( isNaN(float.init));
assert( isNaN(-double.init));
assert( isNaN(real.nan));
assert( isNaN(-real.nan));
assert(!isNaN(cast(float) 53.6));
assert(!isNaN(cast(real)-53.6));
isNaN)
assert((local variable) const(sparkles.test_runner.tier0.Tier0Stats) inTimedinTimed.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw - (local variable) const(sparkles.test_runner.tier0.Tier0Stats) inBetweeninBetween.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw > 16,
string std.conv.text!(string, const(double), string, const(double))(string __param_0, const(double) __param_1, string __param_2, const(double) __param_3) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text("writes in timed must count but in between must not; timed=",
(local variable) const(sparkles.test_runner.tier0.Tier0Stats) inTimedinTimed.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw, " between=", (local variable) const(sparkles.test_runner.tier0.Tier0Stats) inBetweeninBetween.(field) double sparkles.test_runner.tier0.Tier0Stats.syscwwrite syscalls per iteration
syscw));
}
@("tier0.Tier0Group.selfCostSubtracted")
@system
unittest
{
import (package) stdstd.(module) std.convA one-stop shop for converting values from one type to another.
Category Functions Generic asOriginalType castFrom parse to toChars bitCast Strings text wtext dtext writeText writeWText writeDText hexString Numeric octal roundTo signed unsigned Exceptions ConvException ConvOverflowException
Source
std/conv.d
conv : (alias template) text = std.conv.text(T...)(T args) if (T.length > 0)Convenience functions for converting one or more arguments
of any type into _text (the three character widths).
text;
import (package) stdstd.(module) std.mathContains the elementary mathematical functions (powers, roots,
and trigonometric functions), and low-level floating-point operations.
Mathematical special functions are available in std.mathspecial.
Category Members Constants E PI PI_2 PI4 M1_PI M2_PI M2_SQRTPI LN10 LN2 LOG2 LOG2E LOG2T LOG10E SQRT2 SQRT1_2 Algebraic abs fabs sqrt cbrt hypot poly nextPow2 truncPow2 Trigonometry sin cos tan asin acos atan atan2 sinh cosh tanh asinh acosh atanh Rounding ceil floor round lround trunc rint lrint nearbyint rndtol quantize Exponentiation & Logarithms pow powmod exp exp2 expm1 ldexp frexp log log2 log10 logb ilogb log1p scalbn Remainder fmod modf remainder remquo Floating-point operations approxEqual feqrel fdim fmax fmin fma isClose nextDown nextUp nextafter NaN getNaNPayload cmp Introspection isFinite isIdentical isInfinity isNaN isNormal isSubnormal signbit sgn copysign isPowerOf2 Hardware Control IeeeFlags ieeeFlags resetIeeeFlags FloatingPointControl
The functionality closely follows the IEEE754-2008 standard for
floating-point arithmetic, including the use of camelCase names rather
than C99-style lower case names. All of these functions behave correctly
when presented with an infinity or NaN.
The following IEEE 'real' formats are currently supported:
64 bit Big-endian 'double' (eg PowerPC)
128 bit Big-endian 'quadruple' (eg SPARC)
64 bit Little-endian 'double' (eg x86-SSE2)
80 bit Little-endian, with implied bit 'real80' (eg x87, Itanium)
128 bit Little-endian 'quadruple' (not implemented on any known processor!)
Non-IEEE 128 bit Big-endian 'doubledouble' (eg PowerPC) has partial support
Unlike C, there is no global 'errno' variable. Consequently, almost all of
these functions are pure nothrow.
Source
std/math/package.d
math : (alias template) isNaN = std.math.traits.isNaN(X)(X x) if (isFloatingPoint!X)Determines if $(D_PARAM x) is NaN.
Params:
x = a floating point number.
Returns:
`true` if $(D_PARAM x) is Nan.
isNaN;
// tryOpen calibrates the per-bracket snapshot cost; count reports net
// of it. Assert the calibration CONSTANT directly (same-module access
// to the private field): each empty bracket's own /proc read costs
// ~1 syscr, so a calibration that measured nothing is broken. The
// old form compared two sequentially-run count() passes, whose
// process-wide cross-thread read noise differs between the passes —
// under a loud parallel suite the comparison flaked.
auto (local variable) sparkles.test_runner.tier0.Tier0Group calibratedcalibrated = (struct) sparkles.test_runner.tier0.Tier0GroupThe Tier-0 counter group. No fds; count snapshots the cumulative
counters around each iteration. Carries the calibrated per-bracket
self-cost of the snapshots themselves (see calibrateSelfCost).
Tier0Group.sparkles.test_runner.tier0.Tier0Group sparkles.test_runner.tier0.Tier0Group.tryOpen(bool enabled) @safeEnables collection when enabled and calibrates the snapshot
self-cost; otherwise an unavailable group (mirrors
PerfGroup.tryOpen(false)), so the same call sites work.
tryOpen(true);
import (package) sparklessparkles.(package) sparkles.test_runnertest_runner.(module) sparkles.test_runner.skipFirst-class test skipping: skipTest("reason") aborts the current test and
the runner records it as SKIPPED — a yellow ⊘ result line with the reason
and an N skipped summary segment — instead of the early-return pattern
that silently counts a degraded environment as a pass.
Runtime-only: not usable in @ctfe bodies (the probe compile evaluates
them, and a skip there is a compile error) nor in the extracted
--better-c/--wasm programs (no druntime classes there). Inside a
@benchmark body, prefer skipping at registration time (the top of the
body) — a skipTest inside a deferred benchIter/benchCase closure
skips only that case's row.
skip : (alias) skipTest = noreturn sparkles.test_runner.skip.skipTest(string reason) pure nothrow @nogc @safeAborts the current test, recording it as skipped with reason — for
environment capabilities a test needs but this machine/run lacks (perf
counters, a root-only tracefs, a missing toolchain binary). Callable from
the strictest test bodies: throwing an Error is nothrow-legal, and the
recycled instance keeps it @nogc (the minimal @trusted covers only the
deliberately-@system recycledErrorInstance).
skipTest;
if (!(local variable) sparkles.test_runner.tier0.Tier0Group calibratedcalibrated.bool sparkles.test_runner.tier0.Tier0Group.available() const pure nothrow @nogc @safeWhether Tier-0 counters will be collected (Linux and requested).
available)
noreturn sparkles.test_runner.skip.skipTest(string reason) pure nothrow @nogc @safeAborts the current test, recording it as skipped with reason — for
environment capabilities a test needs but this machine/run lacks (perf
counters, a root-only tracefs, a missing toolchain binary). Callable from
the strictest test bodies: throwing an Error is nothrow-legal, and the
recycled instance keeps it @nogc (the minimal @trusted covers only the
deliberately-@system recycledErrorInstance).
skipTest("tier-0 counters unavailable");
static void void sparkles.test_runner.tier0.__unittest_L471_C5.nop() pure nothrow @nogc @safenop() {}
const (local variable) const(sparkles.test_runner.tier0.Tier0Stats) netnet = (local variable) sparkles.test_runner.tier0.Tier0Group calibratedcalibrated.sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.count!(void function() pure nothrow @nogc @safe, void function() pure nothrow @nogc @safe)(scope void function() pure nothrow @nogc @safe timed, scope void function() pure nothrow @nogc @safe between, uint iters, uint batch = 1u) nothrow @nogc @safeThe counting pass: brackets each timed`()` call with its own pair of
snapshots so between() runs outside the counted window, sums the
per-call deltas, and averages once. Returns per-iteration deltas; an
unavailable source reads nan (it propagates through the sum).
batch brackets that many iterations per snapshot pair, so the two
/proc reads amortize instead of dominating a fast body (the tier-0
analogue of the perf bracket's ioctl cost). Only sound when
between is a no-op — the batched rows — so per-call rows keep
``batch == 1, where this is the original per-iteration loop.
count(&void sparkles.test_runner.tier0.__unittest_L471_C5.nop() pure nothrow @nogc @safenop, &void sparkles.test_runner.tier0.__unittest_L471_C5.nop() pure nothrow @nogc @safenop, 64);
if ((local variable) const(sparkles.test_runner.tier0.Tier0Stats) netnet.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr.bool std.math.traits.isNaN!(const(double))(const(double) x) pure nothrow @nogc @trustedDetermines if x is NaN.
Examples
assert( isNaN(float.init));
assert( isNaN(-double.init));
assert( isNaN(real.nan));
assert( isNaN(-real.nan));
assert(!isNaN(cast(float) 53.6));
assert(!isNaN(cast(real)-53.6));
isNaN)
noreturn sparkles.test_runner.skip.skipTest(string reason) pure nothrow @nogc @safeAborts the current test, recording it as skipped with reason — for
environment capabilities a test needs but this machine/run lacks (perf
counters, a root-only tracefs, a missing toolchain binary). Callable from
the strictest test bodies: throwing an Error is nothrow-legal, and the
recycled instance keeps it @nogc (the minimal @trusted covers only the
deliberately-@system recycledErrorInstance).
skipTest("/proc/self/io unavailable (no per-task I/O accounting)");
assert((local variable) sparkles.test_runner.tier0.Tier0Group calibratedcalibrated.(field) sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.selfCostper-bracket snapshot cost; 0 = uncalibrated
selfCost.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr > 0.5,
string std.conv.text!(string, double)(string __param_0, double __param_1) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text("calibration must measure the bracket's own read; selfCost.syscr=",
(local variable) sparkles.test_runner.tier0.Tier0Group calibratedcalibrated.(field) sparkles.test_runner.tier0.Tier0Stats sparkles.test_runner.tier0.Tier0Group.selfCostper-bracket snapshot cost; 0 = uncalibrated
selfCost.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr));
// And the subtraction engages: netOfCost clamps at 0 and returns non-negative.
assert(!(local variable) const(sparkles.test_runner.tier0.Tier0Stats) netnet.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr.bool std.math.traits.isNaN!(const(double))(const(double) x) pure nothrow @nogc @trustedDetermines if x is NaN.
Examples
assert( isNaN(float.init));
assert( isNaN(-double.init));
assert( isNaN(real.nan));
assert( isNaN(-real.nan));
assert(!isNaN(cast(float) 53.6));
assert(!isNaN(cast(real)-53.6));
isNaN && (local variable) const(sparkles.test_runner.tier0.Tier0Stats) netnet.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr >= 0,
string std.conv.text!(string, const(double), string)(string __param_0, const(double) __param_1, string __param_2) pure @safeConvenience functions for converting one or more arguments
of any type into text (the three character widths).
text("net (", (local variable) const(sparkles.test_runner.tier0.Tier0Stats) netnet.(field) double sparkles.test_runner.tier0.Tier0Stats.syscrread syscalls per iteration (/proc/self/io)
syscr, ") must be non-negative"));
}
}
else version (OSX)
{
import core.stdc.config : c_long;
import core.sys.posix.sys.resource : rusage, RUSAGE_SELF;
import core.sys.posix.sys.time : timeval;
import sparkles.test_runner.perf : readRusageInfo, rusage_info_v4;
/// druntime's Darwin `rusage` hides the BSD tail as `ru_opaque[14]`,
/// but the kernel always fills it — this is the full `__DARWIN_C_FULL`
/// layout from the SDK's `sys/resource.h`, bound to the same symbol.
private struct darwinRusage
{
timeval ru_utime;
timeval ru_stime;
c_long ru_maxrss;
c_long ru_ixrss;
c_long ru_idrss;
c_long ru_isrss;
c_long ru_minflt;
c_long ru_majflt;
c_long ru_nswap;
c_long ru_inblock;
c_long ru_oublock;
c_long ru_msgsnd;
c_long ru_msgrcv;
c_long ru_nsignals;
c_long ru_nvcsw;
c_long ru_nivcsw;
}
static assert(darwinRusage.sizeof == rusage.sizeof,
"the named tail must overlay druntime's ru_opaque[14] exactly");
pragma(mangle, "getrusage")
private extern (C) int darwinGetrusage(int who, darwinRusage* usage) @nogc nothrow;
/// The Tier-0 counter group (macOS): `getrusage`'s fault/context-switch
/// counters plus `proc_pid_rusage`'s lifetime disk-I/O byte counters.
/// The `/proc/self/io` syscall/character fields have no macOS analog —
/// they stay `-1` in every reading and `deltaStats`' per-field guard
/// renders them nan, never fabricated zeros. No calibration: neither
/// source carries a per-bracket read cost worth netting (the same
/// reasoning the linux body applies to its fault counters).
struct Tier0Group
{
private bool enabled;
private static immutable CapabilityAbsence[1] notRequestedAbsence = [
CapabilityAbsence(Capability.counting, "not requested"),
];
/// Whether Tier-0 counters will be collected (requested).
bool available() const @safe pure nothrow @nogc => enabled;
/// Human-readable availability, for a report header.
string status() const @safe pure nothrow
=> enabled
? "getrusage + proc_pid_rusage disk I/O"
: "unavailable (not requested)";
/// What this backend can deliver: scalar counting.
CapabilityReport capabilities() const @safe nothrow
{
if (enabled)
return CapabilityReport(Capability.counting, null);
return CapabilityReport(Capability.none, notRequestedAbsence[]);
}
/// Opens the group unless disabled — nothing can fail here.
static Tier0Group tryOpen(bool enabled) @safe pure nothrow @nogc
=> Tier0Group(enabled);
/// Releases nothing — the group holds no descriptors.
void close() @safe pure nothrow @nogc
{
}
/// Captures one instant's cumulative counters.
Tier0Reading snapshot() const @safe nothrow @nogc
{
Tier0Reading r;
r.syscr = r.syscw = r.rdChars = r.wrChars = -1; // no macOS analog
darwinRusage ru;
if ((() @trusted => darwinGetrusage(RUSAGE_SELF, &ru))() == 0)
{
r.minflt = ru.ru_minflt;
r.majflt = ru.ru_majflt;
// XNU reports but never maintains ru_nvcsw (probed live on
// Darwin 25.3: 0 → 0 across 32 explicit sleeps, while
// minflt/majflt/nivcsw all tick) — a permanently-dead field
// must be absent, not a confident 0.00 column.
r.volCs = -1;
r.involCs = ru.ru_nivcsw;
r.rusageOk = true;
}
rusage_info_v4 info;
if (readRusageInfo(info))
{
r.rdBytes = info.ri_diskio_bytesread;
r.wrBytes = info.ri_diskio_byteswritten;
r.ioOk = true;
}
else
r.rdBytes = r.wrBytes = -1;
return r;
}
/// The counting pass: snapshot pairs bracketing `batch` iterations
/// each, per-iteration averages (nan propagates through the sum for
/// absent fields).
///
/// `batch` amortizes the bracket's own two snapshots, which would
/// otherwise dominate a fast body — the same reason the perf tier
/// batches its ioctl pair (SPEC §6.1). Reordering `between()` after
/// its batch is only sound when it is a no-op, so per-call rows keep
/// `batch == 1`, which is exactly the original per-iteration loop.
Tier0Stats count(Timed, Between)(scope Timed timed, scope Between between,
uint iters, uint batch = 1)
in (iters > 0)
{
Tier0Stats sum;
const k = batch == 0 ? 1 : batch;
uint done;
while (done < iters)
{
const n = k < iters - done ? k : iters - done;
done += n;
const start = snapshot();
foreach (_; 0 .. n)
timed();
const end = snapshot();
foreach (_; 0 .. n)
between();
// Raw (divisor 1): `sum` accumulates the whole pass, which the
// 1/iters below averages — correct for any batch size.
const one = deltaStats(start, end, 1);
sum.minflt += one.minflt;
sum.majflt += one.majflt;
sum.volCs += one.volCs;
sum.involCs += one.involCs;
sum.syscr += one.syscr;
sum.syscw += one.syscw;
sum.rdChars += one.rdChars;
sum.wrChars += one.wrChars;
sum.rdBytes += one.rdBytes;
sum.wrBytes += one.wrBytes;
}
const inv = 1.0 / iters;
sum.iters = iters;
sum.minflt *= inv;
sum.majflt *= inv;
sum.volCs *= inv;
sum.involCs *= inv;
sum.syscr *= inv;
sum.syscw *= inv;
sum.rdChars *= inv;
sum.wrChars *= inv;
sum.rdBytes *= inv;
sum.wrBytes *= inv;
return sum;
}
/// The tier-0 deltas across one window, as window totals.
Tier0Stats windowStats(in Tier0Reading a, in Tier0Reading b)
const @safe pure nothrow @nogc
=> deltaStats(a, b, 1);
}
@("tier0.Tier0Group.darwinSnapshotMonotonic")
@system
unittest
{
auto g = Tier0Group.tryOpen(true);
assert(g.available);
const a = g.snapshot();
assert(a.rusageOk, "getrusage works on macOS");
assert(a.syscr == -1, "no /proc/self/io analog — guarded, not zero");
assert(a.volCs == -1, "XNU never maintains ru_nvcsw — dead, not zero");
// Fault in fresh pages so the maintained fields provably MOVE — a
// reported-but-dead counter must never masquerade as a live one.
auto pages = new ubyte[](4 << 20);
pages[] = 0xab;
const b = g.snapshot();
import std.math : isNaN;
const s = g.windowStats(a, b);
assert(s.syscr.isNaN && s.rdChars.isNaN && s.volCs.isNaN,
"absent/dead fields are nan, never fabricated zeros");
assert(!s.minflt.isNaN, "the rusage fields are real");
assert(s.minflt > 0, "4 MiB of faulted pages moves minflt");
assert(pages[0] == 0xab);
if (a.ioOk)
assert(b.rdBytes >= a.rdBytes, "disk-I/O bytes are monotonic");
}
}
else
{
/// Non-Linux, non-macOS stub: Tier-0 counters are permanently
/// unavailable.
struct Tier0Group
{
private static immutable CapabilityAbsence[1] stubAbsence = [
CapabilityAbsence(Capability.counting, "not Linux"),
];
bool available() const @safe pure nothrow @nogc => false;
string status() const @safe pure nothrow => "unavailable (not Linux)";
CapabilityReport capabilities() const @safe pure nothrow @nogc
=> CapabilityReport(Capability.none, stubAbsence[]);
static Tier0Group tryOpen(bool) @safe pure nothrow @nogc => Tier0Group();
void close() @safe pure nothrow @nogc {}
Tier0Stats count(Timed, Between)(scope Timed, scope Between, uint, uint = 1)
{
assert(false, "Tier-0 counters are Linux-only");
}
Tier0Reading snapshot() @safe pure nothrow @nogc => Tier0Reading();
Tier0Stats windowStats(in Tier0Reading, in Tier0Reading)
const @safe pure nothrow @nogc
=> assert(false, "Tier-0 counters are Linux-only");
}
}
/// A counter net of its calibrated per-bracket cost, clamped at zero;
/// `nan` (source unavailable) passes through untouched. Platform-neutral:
/// the darwin perf body (proc_pid_rusage fixed counters) nets its bracket
/// cost through the same helper.
package double double sparkles.test_runner.tier0.netOfCost(double total, double cost) pure nothrow @nogc @safeA counter net of its calibrated per-bracket cost, clamped at zero;
nan (source unavailable) passes through untouched. Platform-neutral:
the darwin perf body (proc_pid_rusage fixed counters) nets its bracket
cost through the same helper.
netOfCost(double (parameter) double totaltotal, double (parameter) double costcost) @safe pure nothrow @nogc
{
import (package) stdstd.(package) std.algorithmalgorithm.(module) std.algorithm.comparisonThis is a submodule of std.algorithm.
It contains generic comparison algorithms.
Function Name Description among Checks if a value is among a set of values, e.g. if (v.among(1, 2, 3)) // v is 1, 2 or 3 castSwitch (new A()).castSwitch((A a)=>1,(B b)=>2) returns 1. clamp clamp(1, 3, 6) returns 3. clamp(4, 3, 6) returns 4. cmp cmp("abc", "abcd") is -1, cmp("abc", "aba") is 1, and cmp("abc", "abc") is 0. either Return first parameter p that passes an if (p) test, e.g. either(0, 42, 43) returns 42. equal Compares ranges for element-by-element equality, e.g. equal([1, 2, 3], [1.0, 2.0, 3.0]) returns true. isPermutation isPermutation([1, 2], [2, 1]) returns true. isSameLength isSameLength([1, 2, 3], [4, 5, 6]) returns true. levenshteinDistance levenshteinDistance("kitten", "sitting") returns 3 by using the Levenshtein distance algorithm. levenshteinDistanceAndPath levenshteinDistanceAndPath("kitten", "sitting") returns tuple(3, "snnnsni") by using the Levenshtein distance algorithm. max max(3, 4, 2) returns 4. min min(3, 4, 2) returns 2. mismatch mismatch("oh hi", "ohayo") returns tuple(" hi", "ayo"). predSwitch 2.predSwitch(1, "one", 2, "two", 3, "three") returns "two".
Source
std/algorithm/comparison.d
comparison : (alias template) max = std.algorithm.comparison.max(T...)(T args) if (T.length >= 2 && !is(CommonType!T == void))Iterates the passed arguments and returns the maximum value.
Params:
args = The values to select the maximum from. At least two arguments must
be passed, and they must be comparable with <.
Returns:
The maximum of the passed-in values. The type of the returned value is
the type among the passed arguments that is able to store the largest value.
If at least one of the arguments is NaN, the result is an unspecified value.
See $(REF maxElement, std,algorithm,searching) for examples on how to cope
with NaNs.
See_Also:
$(REF maxElement, std,algorithm,searching)
max;
import (package) stdstd.(module) std.mathContains the elementary mathematical functions (powers, roots,
and trigonometric functions), and low-level floating-point operations.
Mathematical special functions are available in std.mathspecial.
Category Members Constants E PI PI_2 PI4 M1_PI M2_PI M2_SQRTPI LN10 LN2 LOG2 LOG2E LOG2T LOG10E SQRT2 SQRT1_2 Algebraic abs fabs sqrt cbrt hypot poly nextPow2 truncPow2 Trigonometry sin cos tan asin acos atan atan2 sinh cosh tanh asinh acosh atanh Rounding ceil floor round lround trunc rint lrint nearbyint rndtol quantize Exponentiation & Logarithms pow powmod exp exp2 expm1 ldexp frexp log log2 log10 logb ilogb log1p scalbn Remainder fmod modf remainder remquo Floating-point operations approxEqual feqrel fdim fmax fmin fma isClose nextDown nextUp nextafter NaN getNaNPayload cmp Introspection isFinite isIdentical isInfinity isNaN isNormal isSubnormal signbit sgn copysign isPowerOf2 Hardware Control IeeeFlags ieeeFlags resetIeeeFlags FloatingPointControl
The functionality closely follows the IEEE754-2008 standard for
floating-point arithmetic, including the use of camelCase names rather
than C99-style lower case names. All of these functions behave correctly
when presented with an infinity or NaN.
The following IEEE 'real' formats are currently supported:
64 bit Big-endian 'double' (eg PowerPC)
128 bit Big-endian 'quadruple' (eg SPARC)
64 bit Little-endian 'double' (eg x86-SSE2)
80 bit Little-endian, with implied bit 'real80' (eg x87, Itanium)
128 bit Little-endian 'quadruple' (not implemented on any known processor!)
Non-IEEE 128 bit Big-endian 'doubledouble' (eg PowerPC) has partial support
Unlike C, there is no global 'errno' variable. Consequently, almost all of
these functions are pure nothrow.
Source
std/math/package.d
math : (alias template) isNaN = std.math.traits.isNaN(X)(X x) if (isFloatingPoint!X)Determines if $(D_PARAM x) is NaN.
Params:
x = a floating point number.
Returns:
`true` if $(D_PARAM x) is Nan.
isNaN;
return (parameter) double totaltotal.bool std.math.traits.isNaN!double(double x) pure nothrow @nogc @trustedDetermines if x is NaN.
Examples
assert( isNaN(float.init));
assert( isNaN(-double.init));
assert( isNaN(real.nan));
assert( isNaN(-real.nan));
assert(!isNaN(cast(float) 53.6));
assert(!isNaN(cast(real)-53.6));
isNaN ? (parameter) double totaltotal : double std.algorithm.comparison.max!(double, double)(double a, double b) pure nothrow @nogc @safeIterates the passed arguments and returns the maximum value.
Examples
int a = 5;
short b = 6;
double c = 2;
auto d = max(a, b);
assert(is(typeof(d) == int));
assert(d == 6);
auto e = min(a, b, c);
assert(is(typeof(e) == double));
assert(e == 2);
max(0.0, (parameter) double totaltotal - (parameter) double costcost);
}
@("tier0.netOfCost")
@safe pure nothrow @nogc
unittest
{
import (package) stdstd.(module) std.mathContains the elementary mathematical functions (powers, roots,
and trigonometric functions), and low-level floating-point operations.
Mathematical special functions are available in std.mathspecial.
Category Members Constants E PI PI_2 PI4 M1_PI M2_PI M2_SQRTPI LN10 LN2 LOG2 LOG2E LOG2T LOG10E SQRT2 SQRT1_2 Algebraic abs fabs sqrt cbrt hypot poly nextPow2 truncPow2 Trigonometry sin cos tan asin acos atan atan2 sinh cosh tanh asinh acosh atanh Rounding ceil floor round lround trunc rint lrint nearbyint rndtol quantize Exponentiation & Logarithms pow powmod exp exp2 expm1 ldexp frexp log log2 log10 logb ilogb log1p scalbn Remainder fmod modf remainder remquo Floating-point operations approxEqual feqrel fdim fmax fmin fma isClose nextDown nextUp nextafter NaN getNaNPayload cmp Introspection isFinite isIdentical isInfinity isNaN isNormal isSubnormal signbit sgn copysign isPowerOf2 Hardware Control IeeeFlags ieeeFlags resetIeeeFlags FloatingPointControl
The functionality closely follows the IEEE754-2008 standard for
floating-point arithmetic, including the use of camelCase names rather
than C99-style lower case names. All of these functions behave correctly
when presented with an infinity or NaN.
The following IEEE 'real' formats are currently supported:
64 bit Big-endian 'double' (eg PowerPC)
128 bit Big-endian 'quadruple' (eg SPARC)
64 bit Little-endian 'double' (eg x86-SSE2)
80 bit Little-endian, with implied bit 'real80' (eg x87, Itanium)
128 bit Little-endian 'quadruple' (not implemented on any known processor!)
Non-IEEE 128 bit Big-endian 'doubledouble' (eg PowerPC) has partial support
Unlike C, there is no global 'errno' variable. Consequently, almost all of
these functions are pure nothrow.
Source
std/math/package.d
math : (alias template) isNaN = std.math.traits.isNaN(X)(X x) if (isFloatingPoint!X)Determines if $(D_PARAM x) is NaN.
Params:
x = a floating point number.
Returns:
`true` if $(D_PARAM x) is Nan.
isNaN;
assert(double sparkles.test_runner.tier0.netOfCost(double total, double cost) pure nothrow @nogc @safeA counter net of its calibrated per-bracket cost, clamped at zero;
nan (source unavailable) passes through untouched. Platform-neutral:
the darwin perf body (proc_pid_rusage fixed counters) nets its bracket
cost through the same helper.
netOfCost(3.0, 1.0) == 2.0);
assert(double sparkles.test_runner.tier0.netOfCost(double total, double cost) pure nothrow @nogc @safeA counter net of its calibrated per-bracket cost, clamped at zero;
nan (source unavailable) passes through untouched. Platform-neutral:
the darwin perf body (proc_pid_rusage fixed counters) nets its bracket
cost through the same helper.
netOfCost(0.5, 1.0) == 0.0, "clamped: never negative");
assert(double sparkles.test_runner.tier0.netOfCost(double total, double cost) pure nothrow @nogc @safeA counter net of its calibrated per-bracket cost, clamped at zero;
nan (source unavailable) passes through untouched. Platform-neutral:
the darwin perf body (proc_pid_rusage fixed counters) nets its bracket
cost through the same helper.
netOfCost(double.(constant) double double.nan = nannan, 1.0).bool std.math.traits.isNaN!double(double x) pure nothrow @nogc @trustedDetermines if x is NaN.
Examples
assert( isNaN(float.init));
assert( isNaN(-double.init));
assert( isNaN(real.nan));
assert( isNaN(-real.nan));
assert(!isNaN(cast(float) 53.6));
assert(!isNaN(cast(real)-53.6));
isNaN, "unavailable stays unavailable");
}
// Whichever body the platform built (real or stub) satisfies the backend
// contract, including the optional snapshot/delta primitive.
static assert((template instance) sparkles.test_runner.capability.isCounterBackend!(sparkles.test_runner.tier0.Tier0Group)isCounterBackend!(struct) sparkles.test_runner.tier0.Tier0GroupThe Tier-0 counter group. No fds; count snapshots the cumulative
counters around each iteration. Carries the calibrated per-bracket
self-cost of the snapshots themselves (see calibrateSelfCost).
Tier0Group);
static assert((template instance) sparkles.test_runner.capability.hasSnapshot!(sparkles.test_runner.tier0.Tier0Group)hasSnapshot!(struct) sparkles.test_runner.tier0.Tier0GroupThe Tier-0 counter group. No fds; count snapshots the cumulative
counters around each iteration. Carries the calibrated per-bracket
self-cost of the snapshots themselves (see calibrateSelfCost).
Tier0Group);
static assert(!(template instance) sparkles.test_runner.capability.hasNamedColumns!(sparkles.test_runner.tier0.Tier0Group)hasNamedColumns!(struct) sparkles.test_runner.tier0.Tier0GroupThe Tier-0 counter group. No fds; count snapshots the cumulative
counters around each iteration. Carries the calibrated per-bracket
self-cost of the snapshots themselves (see calibrateSelfCost).
Tier0Group);
@("tier0.Tier0Group.capabilities")
@safe
unittest
{
// Linux and macOS both have real bodies with the same contract; every
// other platform is the permanently-unavailable stub.
bool (local variable) bool realBodyrealBody;
version (linuxlinux)
(local variable) bool realBodyrealBody = true;
version (OSXOSX)
realBody = true;
auto (local variable) sparkles.test_runner.tier0.Tier0Group offoff = (struct) sparkles.test_runner.tier0.Tier0GroupThe Tier-0 counter group. No fds; count snapshots the cumulative
counters around each iteration. Carries the calibrated per-bracket
self-cost of the snapshots themselves (see calibrateSelfCost).
Tier0Group.sparkles.test_runner.tier0.Tier0Group sparkles.test_runner.tier0.Tier0Group.tryOpen(bool enabled) @safeEnables collection when enabled and calibrates the snapshot
self-cost; otherwise an unavailable group (mirrors
PerfGroup.tryOpen(false)), so the same call sites work.
tryOpen(false);
assert(!(local variable) sparkles.test_runner.tier0.Tier0Group offoff.sparkles.test_runner.capability.CapabilityReport sparkles.test_runner.tier0.Tier0Group.capabilities() const pure nothrow @nogc @safeWhat this backend can deliver: process-scope resource counting —
present whenever requested (Linux needs no privilege for it).
capabilities.bool sparkles.test_runner.capability.has(in sparkles.test_runner.capability.CapabilityReport r, sparkles.test_runner.capability.Capability flag) pure nothrow @nogc @safeWhether flag is advertised present.
has((enum) sparkles.test_runner.capability.CapabilityOne flag per survey concern (plus real-world sub-splits). Advertised per
backend instance after its open handshake.
Capability.(enum value) sparkles.test_runner.capability.Capability.counting = 1uconcern 1: scalar counting
counting));
if ((local variable) bool realBodyrealBody)
{
assert((local variable) sparkles.test_runner.tier0.Tier0Group offoff.sparkles.test_runner.capability.CapabilityReport sparkles.test_runner.tier0.Tier0Group.capabilities() const pure nothrow @nogc @safeWhat this backend can deliver: process-scope resource counting —
present whenever requested (Linux needs no privilege for it).
capabilities.string sparkles.test_runner.capability.reasonFor(in sparkles.test_runner.capability.CapabilityReport r, sparkles.test_runner.capability.Capability flag) pure nothrow @nogc @safeThe reason flag is absent; null when present or outside the report's
domain. (Returning the second-level slice out of an in report is legal
under dip1000 — scope is non-transitive; a helper returning the
first-level absences slice itself would not compile.)
reasonFor((enum) sparkles.test_runner.capability.CapabilityOne flag per survey concern (plus real-world sub-splits). Advertised per
backend instance after its open handshake.
Capability.(enum value) sparkles.test_runner.capability.Capability.counting = 1uconcern 1: scalar counting
counting) == "not requested");
auto (local variable) sparkles.test_runner.tier0.Tier0Group onon = (struct) sparkles.test_runner.tier0.Tier0GroupThe Tier-0 counter group. No fds; count snapshots the cumulative
counters around each iteration. Carries the calibrated per-bracket
self-cost of the snapshots themselves (see calibrateSelfCost).
Tier0Group.sparkles.test_runner.tier0.Tier0Group sparkles.test_runner.tier0.Tier0Group.tryOpen(bool enabled) @safeEnables collection when enabled and calibrates the snapshot
self-cost; otherwise an unavailable group (mirrors
PerfGroup.tryOpen(false)), so the same call sites work.
tryOpen(true);
scope (exit)
(local variable) sparkles.test_runner.tier0.Tier0Group onon.void sparkles.test_runner.tier0.Tier0Group.close() pure nothrow @nogc @safeNothing to release; present for surface parity with PerfGroup.
close();
assert((local variable) sparkles.test_runner.tier0.Tier0Group onon.sparkles.test_runner.capability.CapabilityReport sparkles.test_runner.tier0.Tier0Group.capabilities() const pure nothrow @nogc @safeWhat this backend can deliver: process-scope resource counting —
present whenever requested (Linux needs no privilege for it).
capabilities.bool sparkles.test_runner.capability.has(in sparkles.test_runner.capability.CapabilityReport r, sparkles.test_runner.capability.Capability flag) pure nothrow @nogc @safeWhether flag is advertised present.
has((enum) sparkles.test_runner.capability.CapabilityOne flag per survey concern (plus real-world sub-splits). Advertised per
backend instance after its open handshake.
Capability.(enum value) sparkles.test_runner.capability.Capability.counting = 1uconcern 1: scalar counting
counting));
assert((local variable) sparkles.test_runner.tier0.Tier0Group onon.sparkles.test_runner.capability.CapabilityReport sparkles.test_runner.tier0.Tier0Group.capabilities() const pure nothrow @nogc @safeWhat this backend can deliver: process-scope resource counting —
present whenever requested (Linux needs no privilege for it).
capabilities.string sparkles.test_runner.capability.reasonFor(in sparkles.test_runner.capability.CapabilityReport r, sparkles.test_runner.capability.Capability flag) pure nothrow @nogc @safeThe reason flag is absent; null when present or outside the report's
domain. (Returning the second-level slice out of an in report is legal
under dip1000 — scope is non-transitive; a helper returning the
first-level absences slice itself would not compile.)
reasonFor((enum) sparkles.test_runner.capability.CapabilityOne flag per survey concern (plus real-world sub-splits). Advertised per
backend instance after its open handshake.
Capability.(enum value) sparkles.test_runner.capability.Capability.counting = 1uconcern 1: scalar counting
counting) is null);
}
else
assert((local variable) sparkles.test_runner.tier0.Tier0Group offoff.sparkles.test_runner.capability.CapabilityReport sparkles.test_runner.tier0.Tier0Group.capabilities() const pure nothrow @nogc @safeWhat this backend can deliver: process-scope resource counting —
present whenever requested (Linux needs no privilege for it).
capabilities.string sparkles.test_runner.capability.reasonFor(in sparkles.test_runner.capability.CapabilityReport r, sparkles.test_runner.capability.Capability flag) pure nothrow @nogc @safeThe reason flag is absent; null when present or outside the report's
domain. (Returning the second-level slice out of an in report is legal
under dip1000 — scope is non-transitive; a helper returning the
first-level absences slice itself would not compile.)
reasonFor((enum) sparkles.test_runner.capability.CapabilityOne flag per survey concern (plus real-world sub-splits). Advertised per
backend instance after its open handshake.
Capability.(enum value) sparkles.test_runner.capability.Capability.counting = 1uconcern 1: scalar counting
counting) == "not Linux");
}