* @param {string} api
* @param {string} difficulty
* @param {number} effort
- * @param {boolean }debug
*/
- async function sequenceGenerateValidate (api, difficulty, effort, debug) {
- let start = 0, end = 0, duration = 0, result = null, check = false
+ async function sequenceGenerateValidate (api, difficulty, effort) {
+ let start = end = duration = 0, result = null, check = false
+ const options = { api, difficulty, effort, debug: true }
const hash = random()
start = performance.now()
- result = await NanoPow.work_generate(hash, {api, debug, difficulty, effort})
- check = await NanoPow.work_validate(result.work, result.hash, {api, debug, difficulty, effort})
+ result = await NanoPow.work_generate(hash, options)
+ check = await NanoPow.work_validate(result.work, result.hash, options)
end = performance.now()
duration = end - start
/**
* @param {string} api
- * @param {boolean} debug
*/
- async function selfCheck (api, debug) {
+ async function selfCheck (api) {
document.getElementById('status').innerHTML = `RUNNING SELF-CHECK`
logger.log(`%cNanoPow`, 'color:green', 'Checking validation against known values')
- const options = { api, debug }
+ const options = { api, debug: true }
// Generate once on load to compile shaders and initialize buffers
await NanoPow.work_generate(random(), { ...options, difficulty: '0' })
* @param {string} api
* @param {string} difficulty
* @param {number} effort
- * @param {boolean} debug
* @param {number} size
* @param {number} runs
*/
- async function test (api, difficulty, effort, debug, size, runs) {
- logger.isEnabled = debug
+ async function test (api, difficulty, effort, size, runs) {
+ logger.isEnabled = true
const type = api
api = type.toLowerCase()
- await selfCheck(api, debug)
+ await selfCheck(api)
Cache.clear()
logger.log(`%cNanoPow ${type}`, 'color:green', `Calculate truncated harmonic mean of the truncated arithmetic rate of generating proof-of-work across ${runs} runs of ${size} samples.`)
const rates = []
for (let j = 0; j < size; j++) {
document.getElementById('status').innerHTML = `TESTING IN PROGRESS. THIS MAY TAKE A LONG TIME. ${i}/${runs} ${j}/${size}<br/>`
try {
- const duration = await sequenceGenerateValidate(api, difficulty, effort, debug)
+ const duration = await sequenceGenerateValidate(api, difficulty, effort)
times.push(duration)
} catch (err) {
document.getElementById('output').innerHTML += `Error: ${err.message}<br/>`
const api = document.getElementById('api')
const difficulty = document.getElementById('difficulty')
const effort = document.getElementById('effort')
- const debug = document.getElementById('debug')
const size = document.getElementById('size')
const runs = document.getElementById('runs')
- test(api.value, difficulty.value, +effort.value, debug.checked, +size.value, +runs.value)
+ test(api.value, difficulty.value, +effort.value, +size.value, +runs.value)
.then(() => {
event.target.disabled = false
})
<body>
<h1>Speed test for nano-pow</h1>
<h2><a href="https://www.npmjs.com/package/nano-pow">https://www.npmjs.com/package/nano-pow</a></h2>
- <p>This benchmark tests a browser-based proof-of-work implementation for the cryptocurrency Nano. A random 32-byte value is generated for a block hash, and then the test uses this value to find a nonce that meets a minimum threshold.</p>
- <p>NanoPow uses cutting edge WebGPU technology, and not all browsers support it.</p>
- <p>NanoPow uses WebGL 2.0 as a fallback option if WebGPU is not detected. It uses a WASM module if neither GPU API is available.</p>
- <p>Times below are in milliseconds and are summarized by various averaging methods.</p>
+ <p>This benchmark tests a browser-based proof-of-work implementation for the cryptocurrency Nano.</p>
+ <p>NanoPow uses cutting edge WebGPU technology, and not all browsers support it. WebGL 2.0 is used as a fallback option if WebGPU is not detected, and a WASM module is used if neither GPU API is available.</p>
+ <p>Times are measured in milliseconds and are summarized by various averaging methods.</p>
<p>Level of Effort depends on hardware and does not guarantee faster results.</p>
+ <p>This benchmark operates by running a sequence of functions. First, a random 32-byte value is generated for a block hash. Next, the benchmark timer begins and NanoPow uses the block hash to find a nonce that meets a minimum threshold. Finally, it validates that nonce and then ends the timer.</p>
<ul>
- <li>Each work_generate call is individually timed.</li>
- <li>Each test is comprised of the specified iterations of calls.</li>
+ <li>Each generate-validate sequence is timed as a unit.</li>
+ <li>Each test is comprised of the specified iterations of sequence units.</li>
<li>Each test run is comprised of the specified iterations of tests.</li>
</ul>
<p>The final score is displayed as "work-per-second" and is calculated as follows:</p>
<ol>
<li>For each test run:
<ol>
- <li>Collect all the work_generate timings for the test run.</li>
+ <li>Collect all the generate-validate sequence timings for the test run.</li>
<li>Truncate the results by eliminating the fastest 10% and slowest 10% of sequence timings.</li>
<li>Calculate the arithmetic mean (average) of the truncated results.</li>
</ol>
<div class="hex"><input id="difficulty" type="text" value="FFFFFFF800000000" /></div>
<label for="effort">Effort (1-32)</label>
<input id="effort" type="number" min="1" max="32" />
- <label for="debug">Debug</label>
- <input id="debug" type="checkbox" />
<label for="size">Test Size</label>
<input id="size" type="number" value="100" min="1" autofocus />
<label for="runs">Test Runs</label>