UNPKG

@eagleoutice/flowr-dev

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

90 lines 3.55 kB
"use strict"; /** * A small, fixed, and purely synthetic workload used to calibrate the benchmark results. * * Publishing its runtime alongside the real measurements allows a viewer to normalize the other numbers by it, * and hence to cancel out how fast or how loaded the machine was that produced them. * The workload must therefore stay deterministic (no file system, no R session, no randomness). * * Changing the work, the round count, or the way the repetitions are reduced puts every future run on a * new scale, incomparable to the published history. Whoever changes it has to say so in the name of the * measurement (`calibration v2`, ...). * @module */ Object.defineProperty(exports, "__esModule", { value: true }); exports.CalibrationSize = exports.CalibrationRounds = exports.CalibrationSamples = exports.CalibrationReps = void 0; exports.runCalibration = runCalibration; exports.calibrationChecksum = calibrationChecksum; /** How often the {@link calibrationBatch} is timed within one {@link runCalibration} call. */ exports.CalibrationReps = 4; /** How many files of a suite carry the calibration, which describes the machine and not the file. */ exports.CalibrationSamples = 8; /** How many {@link calibrationRound}s make up one timed batch. */ exports.CalibrationRounds = 256; /** How many elements a single {@link calibrationRound} works on. */ exports.CalibrationSize = 4096; let sink = 0; function nextRandom(state) { state ^= state << 13; state ^= state >>> 17; state ^= state << 5; return state | 0; } function calibrationRound(round) { let state = 0x1337 + round; const numbers = new Array(exports.CalibrationSize); for (let i = 0; i < exports.CalibrationSize; i++) { state = nextRandom(state); numbers[i] = state % 100_000; } numbers.sort((a, b) => a - b); const nodes = []; const map = new Map(); const seen = new Set(); for (let i = 0; i < exports.CalibrationSize; i++) { const key = `k${numbers[i] % 512}`; nodes.push({ id: key, value: numbers[i], next: i + 1 }); map.set(key, (map.get(key) ?? 0) + i); seen.add(key); } let checksum = seen.size; for (const [key, value] of map) { checksum = (checksum + key.length * value) | 0; } for (const node of nodes) { checksum = (checksum + node.id.length + (node.value & 0xff) + node.next) | 0; } for (let i = 0; i < exports.CalibrationSize; i++) { checksum = (checksum + Math.floor(Math.sqrt(numbers[i] + 1))) | 0; } return checksum; } function calibrationBatch() { let checksum = 0; for (let round = 0; round < exports.CalibrationRounds; round++) { checksum = (checksum + calibrationRound(round)) | 0; } return checksum; } /** * Times {@link calibrationBatch} {@link CalibrationReps} times and reports the fastest of them. * @returns the nanoseconds the fastest batch took */ function runCalibration() { sink = calibrationRound(0); let best = undefined; for (let rep = 0; rep < exports.CalibrationReps; rep++) { const start = process.hrtime.bigint(); sink = (sink + calibrationBatch()) | 0; const took = process.hrtime.bigint() - start; if (best === undefined || took < best) { best = took; } } return best ?? 0n; } /** the checksum of the rounds run so far, only exposed so that the workload has an observable effect */ function calibrationChecksum() { return sink; } //# sourceMappingURL=calibration.js.map