three-blocks-benchmark 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +5 -13
- package/bin/three-blocks-benchmark.mjs +1 -3
- package/browser/harness.js +1 -0
- package/lib/run.mjs +9 -39
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# three-blocks-benchmark
|
|
2
2
|
|
|
3
|
+
## 0.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 02f3072: Devtools: Run shader captures and project checks in Node with fewer dependencies.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [02f3072]
|
|
12
|
+
- @three-blocks/devtools@11.1.0
|
|
13
|
+
- three-blocks@0.12.1
|
|
14
|
+
|
|
3
15
|
## 0.5.1
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# three-blocks-benchmark
|
|
2
2
|
|
|
3
|
-
Reproducible
|
|
3
|
+
Reproducible Node.js benchmarks for Three Blocks, the official three.js r186
|
|
4
4
|
`GaussianSplat` addon, Spark, SuperSplat Viewer 1.31.2, SuperSplat Editor 3.0.0's
|
|
5
5
|
renderer, GaussianSplats3D, and Babylon.js.
|
|
6
6
|
|
|
@@ -18,12 +18,6 @@ Published results and methodology:
|
|
|
18
18
|
|
|
19
19
|
## Run
|
|
20
20
|
|
|
21
|
-
Install Chromium once:
|
|
22
|
-
|
|
23
|
-
```sh
|
|
24
|
-
npx playwright install chromium
|
|
25
|
-
```
|
|
26
|
-
|
|
27
21
|
Run the one-view standard validation from npm:
|
|
28
22
|
|
|
29
23
|
```sh
|
|
@@ -63,12 +57,10 @@ a micro scene.
|
|
|
63
57
|
`--revision <value>` and `--dirty` add optional repository metadata; neither
|
|
64
58
|
Git nor a checkout is required.
|
|
65
59
|
|
|
66
|
-
The CLI
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
[eager-memory]: https://chromium.googlesource.com/chromium/src/+/refs/tags/143.0.7458.0/third_party/blink/web_tests/VirtualTestSuites
|
|
60
|
+
The CLI renders in Node.js through native ANGLE (WebGL) and Dawn (WebGPU).
|
|
61
|
+
Publication runs reject software GPU adapters. Memory sampling records the
|
|
62
|
+
isolated Node process's RSS after forced GC, outside the load and frame clocks;
|
|
63
|
+
these values are not comparable to historical browser heap measurements.
|
|
72
64
|
|
|
73
65
|
Frame timing directly executes each renderer's frame, without waiting for a display
|
|
74
66
|
refresh, and cycles through the three held-out cameras. SuperSplat's complete viewer
|
|
@@ -22,8 +22,6 @@ Options:
|
|
|
22
22
|
--renderer <id> Validate one renderer (not publication evidence)
|
|
23
23
|
--quick Use one view/scene and short measurements
|
|
24
24
|
--omit-captures Write metrics JSON without renderer captures
|
|
25
|
-
--headed Show Chromium
|
|
26
|
-
--headless Hide Chromium (default)
|
|
27
25
|
--revision <value> Record an optional source revision
|
|
28
26
|
--dirty Record that the source tree had changes
|
|
29
27
|
--clean Record that the source tree was clean
|
|
@@ -39,7 +37,7 @@ function parseArgs( rawArgs ) {
|
|
|
39
37
|
const argument = rawArgs[ index ];
|
|
40
38
|
if ( argument === '--quick' ) options.quick = true;
|
|
41
39
|
else if ( argument === '--omit-captures' ) options.omitCaptures = true;
|
|
42
|
-
else if ( argument === '--headed' )
|
|
40
|
+
else if ( argument === '--headed' ) throw new Error( 'Benchmarks run in headless Node.' );
|
|
43
41
|
else if ( argument === '--headless' ) options.headed = false;
|
|
44
42
|
else if ( argument === '--dirty' ) options.workingTreeDirty = true;
|
|
45
43
|
else if ( argument === '--clean' ) options.workingTreeDirty = false;
|
package/browser/harness.js
CHANGED
|
@@ -688,6 +688,7 @@ async function measureBrowserMemory() {
|
|
|
688
688
|
|
|
689
689
|
window.gc?.();
|
|
690
690
|
await new Promise( resolve => requestAnimationFrame( resolve ) );
|
|
691
|
+
if ( typeof globalThis.__THREE_BLOCKS_NODE_MEMORY__ === 'function' ) return { bytes: globalThis.__THREE_BLOCKS_NODE_MEMORY__().rss, source: 'node.process.memoryUsage.rss' };
|
|
691
692
|
if ( typeof performance.measureUserAgentSpecificMemory === 'function' ) {
|
|
692
693
|
|
|
693
694
|
try {
|
package/lib/run.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { launchNodeRenderer } from '@three-blocks/devtools/node';
|
|
1
2
|
import { createHash } from 'node:crypto';
|
|
2
3
|
import { createReadStream } from 'node:fs';
|
|
3
4
|
import fs from 'node:fs/promises';
|
|
@@ -6,7 +7,6 @@ import os from 'node:os';
|
|
|
6
7
|
import path from 'node:path';
|
|
7
8
|
import process from 'node:process';
|
|
8
9
|
import { fileURLToPath } from 'node:url';
|
|
9
|
-
import { chromium } from 'playwright';
|
|
10
10
|
import { PNG } from 'pngjs';
|
|
11
11
|
import { build } from 'vite';
|
|
12
12
|
import {
|
|
@@ -340,7 +340,7 @@ async function runPage( browser, baseUrl, { renderer, suite, item, warmup, frame
|
|
|
340
340
|
await context.close();
|
|
341
341
|
if ( video ) {
|
|
342
342
|
|
|
343
|
-
// The recorder finalizes on close; rename
|
|
343
|
+
// The native recorder finalizes on close; rename its temporary file
|
|
344
344
|
// to the run order so a capture maps back to its stdout line.
|
|
345
345
|
const sequence = String( recordedRuns ++ ).padStart( 3, '0' );
|
|
346
346
|
await video.saveAs( path.join( process.env.TB_RECORD_VIDEO, `${sequence}-${item.id}-${renderer}.webm` ) );
|
|
@@ -354,27 +354,11 @@ async function runPage( browser, baseUrl, { renderer, suite, item, warmup, frame
|
|
|
354
354
|
|
|
355
355
|
let recordedRuns = 0;
|
|
356
356
|
|
|
357
|
-
function gpuSummary( systemInfo ) {
|
|
358
|
-
|
|
359
|
-
const gpu = systemInfo.gpu ?? {};
|
|
360
|
-
return {
|
|
361
|
-
devices: ( gpu.devices ?? [] ).map( device => ( {
|
|
362
|
-
vendorId: device.vendorId,
|
|
363
|
-
deviceId: device.deviceId,
|
|
364
|
-
vendor: device.vendorString,
|
|
365
|
-
device: device.deviceString,
|
|
366
|
-
driverVendor: device.driverVendor,
|
|
367
|
-
driverVersion: device.driverVersion,
|
|
368
|
-
} ) ),
|
|
369
|
-
auxAttributes: gpu.auxAttributes ?? {},
|
|
370
|
-
};
|
|
371
|
-
|
|
372
|
-
}
|
|
373
357
|
|
|
374
358
|
function isPhysicalGpu( gpu ) {
|
|
375
359
|
|
|
376
360
|
const description = JSON.stringify( gpu ).toLowerCase();
|
|
377
|
-
return ! /swiftshader|llvmpipe|software rasterizer/.test( description );
|
|
361
|
+
return Boolean( gpu.vendor && ( gpu.device || gpu.architecture ) ) && gpu.isFallbackAdapter !== true && ! /swiftshader|llvmpipe|software rasterizer/.test( description );
|
|
378
362
|
|
|
379
363
|
}
|
|
380
364
|
|
|
@@ -407,7 +391,8 @@ export async function runBenchmark( options ) {
|
|
|
407
391
|
|
|
408
392
|
}
|
|
409
393
|
const quick = options.quick === true;
|
|
410
|
-
|
|
394
|
+
if ( options.headed === true ) throw new Error( 'Benchmarks run in headless Node.' );
|
|
395
|
+
const headed = false;
|
|
411
396
|
const repetitions = quick ? 1 : 3;
|
|
412
397
|
// Warm each runtime with the same moving-camera sequence used for measurement.
|
|
413
398
|
const warmupFrames = quick ? 2 : 60;
|
|
@@ -517,23 +502,8 @@ export async function runBenchmark( options ) {
|
|
|
517
502
|
}
|
|
518
503
|
const bundleSha256 = await directoryDigest( bundleRoot );
|
|
519
504
|
server = await serveDirectory( bundleRoot, externalFiles );
|
|
520
|
-
browser = await
|
|
521
|
-
|
|
522
|
-
headless: ! headed,
|
|
523
|
-
args: [
|
|
524
|
-
'--enable-unsafe-webgpu',
|
|
525
|
-
'--js-flags=--expose-gc',
|
|
526
|
-
// Chromium's own measure-memory tests use eager collection. The harness
|
|
527
|
-
// samples after forced GC, outside timing, without waiting for idle GC.
|
|
528
|
-
'--enable-blink-features=ForceEagerMeasureMemory',
|
|
529
|
-
// Headless Chromium on macOS otherwise picks SwiftShader, which fails the
|
|
530
|
-
// physical-GPU gate and captures blank frames.
|
|
531
|
-
...( process.platform === 'darwin' ? [ '--use-angle=metal' ] : [] ),
|
|
532
|
-
],
|
|
533
|
-
} );
|
|
534
|
-
const cdp = await browser.newBrowserCDPSession();
|
|
535
|
-
const systemInfo = await cdp.send( 'SystemInfo.getInfo' );
|
|
536
|
-
const gpu = gpuSummary( systemInfo );
|
|
505
|
+
browser = await launchNodeRenderer();
|
|
506
|
+
const gpu = await browser.gpuInfo();
|
|
537
507
|
const physicalGpu = isPhysicalGpu( gpu );
|
|
538
508
|
if ( ! quick && ! physicalGpu ) {
|
|
539
509
|
|
|
@@ -719,7 +689,7 @@ export async function runBenchmark( options ) {
|
|
|
719
689
|
browser: await browser.version(),
|
|
720
690
|
headed,
|
|
721
691
|
physicalGpu,
|
|
722
|
-
memoryMeasurement: '
|
|
692
|
+
memoryMeasurement: 'Node renderer process resident memory after GC, outside timing.',
|
|
723
693
|
gpu,
|
|
724
694
|
os: { platform: process.platform, release: os.release(), architecture: os.arch() },
|
|
725
695
|
cpu: os.cpus()[ 0 ]?.model ?? null,
|
|
@@ -734,7 +704,7 @@ export async function runBenchmark( options ) {
|
|
|
734
704
|
frame: suiteId === 'standard'
|
|
735
705
|
? 'Round-robin held-out-camera update through a complete current-camera sort, index upload and GPU-complete draw, without a display-frame wait; quick uses its single validation view.'
|
|
736
706
|
: 'Camera update through a complete current-camera sort and GPU-complete draw on a deterministic 2.5-degree orbit.',
|
|
737
|
-
memory: '
|
|
707
|
+
memory: 'Node renderer process RSS after forced GC; renderer GPU bytes are secondary because scopes differ.',
|
|
738
708
|
quality: suiteId === 'standard'
|
|
739
709
|
? `PSNR and dm_pix-compatible RGB SSIM on decoded sRGB captures versus held-out ground truth, after ${warmupFrames} stationary frames outside the timing window.`
|
|
740
710
|
: 'Not measured; synthetic micro scenes are performance-only.',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "three-blocks-benchmark",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Reproducible Gaussian splat benchmarks for Three Blocks, three.js r186, Spark, SuperSplat Viewer and Editor 3, GaussianSplats3D, and Babylon.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"three",
|
|
@@ -51,11 +51,11 @@
|
|
|
51
51
|
"@playcanvas/splat-transform": "3.3.3",
|
|
52
52
|
"@playcanvas/supersplat-viewer": "1.31.2",
|
|
53
53
|
"@sparkjsdev/spark": "2.1.0",
|
|
54
|
+
"@three-blocks/devtools": "11.1.0",
|
|
54
55
|
"playcanvas": "2.22.0",
|
|
55
|
-
"playwright": "1.61.1",
|
|
56
56
|
"pngjs": "7.0.0",
|
|
57
57
|
"three": "0.185.1",
|
|
58
|
-
"three-blocks": "0.12.
|
|
58
|
+
"three-blocks": "0.12.1",
|
|
59
59
|
"three-r186": "npm:three@0.186.0",
|
|
60
60
|
"vite": "8.1.3"
|
|
61
61
|
}
|