tiny.profiling.order.contrast
Defined in order.
API (5)
Actions
Public operations.
Types and contracts
Public types and contracts.
Values and defaults
Public values and defaults.
Source
Source: src/profiling/contrast.zig
zig
const std = @import("std");const capture = @import("capture");pub const minimum_repetitions: usize = 2;pub const effect_method = "deterministic_percentile_bootstrap_unpaired_mean_percent_change";pub const Classification = enum { insufficient_repetitions, no_order_effect_observed, order_sensitive_candidate,};pub const Result = struct { fixed_count: usize, random_count: usize, fixed_mean_ns: ?f64, random_mean_ns: ?f64, mean_percent_change: ?f64, effect_interval: ?capture.compare.effect.Interval, classification: Classification,};pub fn summarize( allocator: std.mem.Allocator, workload: []const u8, fixed_samples: []const f64, random_samples: []const f64,) !Result { const fixed_mean = mean(fixed_samples); const random_mean = mean(random_samples); const mean_percent_change = if (fixed_mean != null and random_mean != null and fixed_mean.? != 0) ((random_mean.? / fixed_mean.?) - 1) * 100 else null; const effect_interval = if (fixed_samples.len >= minimum_repetitions and random_samples.len >= minimum_repetitions) interval: { var effect_storage = try capture.compare.EffectStorage.init(allocator, .{ .max_samples_per_distribution = @max( fixed_samples.len, random_samples.len, ), }); defer effect_storage.deinit(allocator); effect_storage.activate(); break :interval try capture.compare.effect.bootstrapMeanPercentChangeInterval( &effect_storage, fixed_samples, random_samples, seed(workload), ); } else null; return .{ .fixed_count = fixed_samples.len, .random_count = random_samples.len, .fixed_mean_ns = fixed_mean, .random_mean_ns = random_mean, .mean_percent_change = mean_percent_change, .effect_interval = effect_interval, .classification = classify(effect_interval), };}fn mean(samples: []const f64) ?f64 { if (samples.len == 0) return null; var total: f64 = 0; for (samples) |sample| total += sample; return total / @as(f64, @floatFromInt(samples.len));}fn classify( effect_interval: ?capture.compare.effect.Interval,) Classification { const interval = effect_interval orelse return .insufficient_repetitions; if (interval.low > 0 or interval.high < 0) { return .order_sensitive_candidate; } return .no_order_effect_observed;}fn seed(workload: []const u8) u64 { var hasher = std.hash.Wyhash.init( capture.compare.effect.bootstrap_seed ^ 0x4f52_4445_525f_4658, ); hasher.update(workload); return hasher.final();}test "order contrast classifies separated repeated process samples" { const result = try summarize( std.testing.allocator, "compiler", &.{ 10, 11, 9, 10 }, &.{ 20, 22, 18, 20 }, ); try std.testing.expectEqual(@as(usize, 4), result.fixed_count); try std.testing.expectEqual(@as(f64, 10), result.fixed_mean_ns.?); try std.testing.expectEqual(@as(f64, 20), result.random_mean_ns.?); try std.testing.expectApproxEqAbs( @as(f64, 100), result.mean_percent_change.?, 0.0001, ); try std.testing.expectEqual( Classification.order_sensitive_candidate, result.classification, ); try std.testing.expect(result.effect_interval.?.low > 0);}test "order contrast keeps low repetition and zero reference inconclusive" { const single = try summarize( std.testing.allocator, "single", &.{10}, &.{20}, ); try std.testing.expectEqual( Classification.insufficient_repetitions, single.classification, ); try std.testing.expect(single.effect_interval == null); const zero = try summarize( std.testing.allocator, "zero", &.{ 0, 0 }, &.{ 1, 2 }, ); try std.testing.expect(zero.mean_percent_change == null); try std.testing.expect(zero.effect_interval == null); try std.testing.expectEqual( Classification.insufficient_repetitions, zero.classification, );}Source: src/profiling/order.zig:10
zig
pub const contrast = @import("contrast.zig");Audit
| Definitions | 6 |
|---|---|
| Public names | 6 |
| Members | 10 |
| Version | 26.7.0 |
| Revision | daab053ee433 |