tool/pathrule_bench.dart times, on the VM or compiled to JavaScript, checkPath of a path of ASCII and of one that R6c projects with its 15 tables, checkComment of a comment of 16 351 bytes, checkTree of 1000 paths, the largest head (65 535 paths checked and their tree), normalizeWords with checkWords, and wordKey with its 600 000 iterations of PBKDF2. Medians of three runs on the VM: 9.5 and 28 microseconds for the paths, 0.68 ms for the comment, 2.0 s for the largest head and 1.14 s for the key; on Node.js 11.8 and 38 microseconds, 0.63 ms, 2.3 s and 0.73 s. The header of tool/pathrule_go_vectors.go says now that its named cases hold both sides of each limit of R2, R3 and R6b. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>v0.11
parent
16c217d744
commit
2c22129030
@ -0,0 +1,103 @@
|
||||
// Timings of the rules of paths and texts and of the key of words (stage
|
||||
// 4a), on the VM or compiled to JavaScript:
|
||||
//
|
||||
// dart run tool/pathrule_bench.dart
|
||||
// dart compile js -O2 -o /tmp/pathrule_bench.js tool/pathrule_bench.dart && node /tmp/pathrule_bench.js
|
||||
//
|
||||
// ignore_for_file: avoid_print
|
||||
library;
|
||||
|
||||
import 'package:datekeys/src/bytes.dart';
|
||||
import 'package:datekeys/src/pathrule.dart';
|
||||
import 'package:datekeys/src/wordkey.dart';
|
||||
|
||||
/// The mean time of [f] in milliseconds, over at least [minRuns] runs and
|
||||
/// about [budgetMs] milliseconds, after one run to warm up.
|
||||
double time(void Function() f, {int minRuns = 3, int budgetMs = 2000}) {
|
||||
f();
|
||||
final sw = Stopwatch()..start();
|
||||
var runs = 0;
|
||||
while (runs < minRuns || sw.elapsedMilliseconds < budgetMs) {
|
||||
f();
|
||||
runs++;
|
||||
}
|
||||
return sw.elapsedMicroseconds / 1000 / runs;
|
||||
}
|
||||
|
||||
String ms(double v) => v < 0.1
|
||||
? '${(v * 1000).toStringAsFixed(1)} µs'
|
||||
: '${v.toStringAsFixed(v < 10 ? 2 : 0)} ms';
|
||||
|
||||
String cp(List<int> runes) => String.fromCharCodes(runes);
|
||||
|
||||
void main() {
|
||||
// A path of ASCII, and one with letters and a symbol that the best-fit
|
||||
// tables project, so that R6c projects it with each of its 15 tables.
|
||||
const ascii = 'fotos/2025/verano/playa con amigos.jpg';
|
||||
final accented =
|
||||
'm${cp([0xfa])}sica/canci${cp([0xf3])}n de cuna ${cp([0x2665])}.mp3';
|
||||
checkPath(ascii);
|
||||
checkPath(accented);
|
||||
print(
|
||||
'checkPath, ${ascii.length} ASCII characters: '
|
||||
'${ms(time(() => checkPath(ascii)))}',
|
||||
);
|
||||
print(
|
||||
'checkPath, ${accented.length} characters with accents and a symbol: '
|
||||
'${ms(time(() => checkPath(accented)))}',
|
||||
);
|
||||
|
||||
// A comment of 16 384 bytes, the longest: lines of Spanish with accents,
|
||||
// an emoji with its selector and a tab.
|
||||
final line = StringBuffer()
|
||||
..write('Querida Ana: te escribo desde la playa, donde el a')
|
||||
..write(cp([0xf1]))
|
||||
..write('o pasado fuimos juntos ')
|
||||
..write(cp([0x2764, 0xfe0f]))
|
||||
..write('\t');
|
||||
var comment = '';
|
||||
while (utf8Bytes('$comment$line\n').length <= maxCommentLen) {
|
||||
comment = '$comment$line\n';
|
||||
}
|
||||
checkComment(comment);
|
||||
print(
|
||||
'checkComment, ${utf8Bytes(comment).length} bytes: '
|
||||
'${ms(time(() => checkComment(comment)))}',
|
||||
);
|
||||
|
||||
// The tree of 1000 paths in 10 folders.
|
||||
final paths = [
|
||||
for (var i = 0; i < 1000; i++) 'carpeta ${i % 10}/foto $i.jpg',
|
||||
];
|
||||
checkTree(paths);
|
||||
print('checkTree, 1000 paths: ${ms(time(() => checkTree(paths)))}');
|
||||
|
||||
// The largest head: 65 535 paths like the second one, in 100 folders,
|
||||
// each checked and then the tree, as the reader of a head does.
|
||||
final head = [
|
||||
for (var i = 0; i < maxImplicitDirs; i++)
|
||||
'carpeta ${i % 100}/canci${cp([0xf3])}n $i ${cp([0x2665])}.mp3',
|
||||
];
|
||||
void checkHead() {
|
||||
head.forEach(checkPath);
|
||||
checkTree(head);
|
||||
}
|
||||
|
||||
print(
|
||||
'checkPath of each and checkTree, 65 535 paths: '
|
||||
'${ms(time(checkHead, minRuns: 1, budgetMs: 0))}',
|
||||
);
|
||||
|
||||
final words = normalizeWords('Perro LUNA casa verde tr${cp([0xe9])}n mar');
|
||||
checkWords(words);
|
||||
print(
|
||||
'normalizeWords and checkWords: '
|
||||
'${ms(time(() => checkWords(normalizeWords('Perro LUNA casa verde tren mar'))))}',
|
||||
);
|
||||
final chain = List<int>.filled(32, 0x52);
|
||||
final id = List<int>.generate(16, (i) => i);
|
||||
print(
|
||||
'wordKey, 600 000 iterations of PBKDF2: '
|
||||
'${ms(time(() => wordKey(words, chain, 1000, id), minRuns: 3, budgetMs: 0))}',
|
||||
);
|
||||
}
|
||||
Loading…
Reference in new issue