| Index: packages/watcher/benchmark/path_set.dart
|
| diff --git a/packages/watcher/benchmark/path_set.dart b/packages/watcher/benchmark/path_set.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..aba3ed750828c24c527c1a14d9cdfe8acce4695d
|
| --- /dev/null
|
| +++ b/packages/watcher/benchmark/path_set.dart
|
| @@ -0,0 +1,147 @@
|
| +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +/// Benchmarks for the PathSet class.
|
| +library watcher.benchmark.path_set;
|
| +
|
| +import 'dart:io';
|
| +import 'dart:math' as math;
|
| +
|
| +import 'package:benchmark_harness/benchmark_harness.dart';
|
| +import 'package:path/path.dart' as p;
|
| +
|
| +import 'package:watcher/src/path_set.dart';
|
| +
|
| +final String root = Platform.isWindows ? r"C:\root" : "/root";
|
| +
|
| +/// Base class for benchmarks on [PathSet].
|
| +abstract class PathSetBenchmark extends BenchmarkBase {
|
| + PathSetBenchmark(String method) : super("PathSet.$method");
|
| +
|
| + final PathSet pathSet = new PathSet(root);
|
| +
|
| + /// Use a fixed [Random] with a constant seed to ensure the tests are
|
| + /// deterministic.
|
| + final math.Random random = new math.Random(1234);
|
| +
|
| + /// Walks over a virtual directory [depth] levels deep invoking [callback]
|
| + /// for each "file".
|
| + ///
|
| + /// Each virtual directory contains ten entries: either subdirectories or
|
| + /// files.
|
| + void walkTree(int depth, callback(String path)) {
|
| + recurse(path, remainingDepth) {
|
| + for (var i = 0; i < 10; i++) {
|
| + var padded = i.toString().padLeft(2, '0');
|
| + if (remainingDepth == 0) {
|
| + callback(p.join(path, "file_$padded.txt"));
|
| + } else {
|
| + var subdir = p.join(path, "subdirectory_$padded");
|
| + recurse(subdir, remainingDepth - 1);
|
| + }
|
| + }
|
| + }
|
| +
|
| + recurse(root, depth);
|
| + }
|
| +}
|
| +
|
| +class AddBenchmark extends PathSetBenchmark {
|
| + AddBenchmark() : super("add()");
|
| +
|
| + final List<String> paths = [];
|
| +
|
| + void setup() {
|
| + // Make a bunch of paths in about the same order we expect to get them from
|
| + // Directory.list().
|
| + walkTree(3, paths.add);
|
| + }
|
| +
|
| + void run() {
|
| + for (var path in paths) pathSet.add(path);
|
| + }
|
| +}
|
| +
|
| +class ContainsBenchmark extends PathSetBenchmark {
|
| + ContainsBenchmark() : super("contains()");
|
| +
|
| + final List<String> paths = [];
|
| +
|
| + void setup() {
|
| + // Add a bunch of paths to the set.
|
| + walkTree(3, (path) {
|
| + pathSet.add(path);
|
| + paths.add(path);
|
| + });
|
| +
|
| + // Add some non-existent paths to test the false case.
|
| + for (var i = 0; i < 100; i++) {
|
| + paths.addAll([
|
| + "/nope",
|
| + "/root/nope",
|
| + "/root/subdirectory_04/nope",
|
| + "/root/subdirectory_04/subdirectory_04/nope",
|
| + "/root/subdirectory_04/subdirectory_04/subdirectory_04/nope",
|
| + "/root/subdirectory_04/subdirectory_04/subdirectory_04/nope/file_04.txt",
|
| + ]);
|
| + }
|
| + }
|
| +
|
| + void run() {
|
| + var contained = 0;
|
| + for (var path in paths) {
|
| + if (pathSet.contains(path)) contained++;
|
| + }
|
| +
|
| + if (contained != 10000) throw "Wrong result: $contained";
|
| + }
|
| +}
|
| +
|
| +class PathsBenchmark extends PathSetBenchmark {
|
| + PathsBenchmark() : super("toSet()");
|
| +
|
| + void setup() {
|
| + walkTree(3, pathSet.add);
|
| + }
|
| +
|
| + void run() {
|
| + var count = 0;
|
| + for (var _ in pathSet.paths) {
|
| + count++;
|
| + }
|
| +
|
| + if (count != 10000) throw "Wrong result: $count";
|
| + }
|
| +}
|
| +
|
| +class RemoveBenchmark extends PathSetBenchmark {
|
| + RemoveBenchmark() : super("remove()");
|
| +
|
| + final List<String> paths = [];
|
| +
|
| + void setup() {
|
| + // Make a bunch of paths. Do this here so that we don't spend benchmarked
|
| + // time synthesizing paths.
|
| + walkTree(3, (path) {
|
| + pathSet.add(path);
|
| + paths.add(path);
|
| + });
|
| +
|
| + // Shuffle the paths so that we delete them in a random order that
|
| + // hopefully mimics real-world file system usage. Do the shuffling here so
|
| + // that we don't spend benchmarked time shuffling.
|
| + paths.shuffle(random);
|
| + }
|
| +
|
| + void run() {
|
| + for (var path in paths) pathSet.remove(path);
|
| + }
|
| +}
|
| +
|
| +main() {
|
| + new AddBenchmark().report();
|
| + new ContainsBenchmark().report();
|
| + new PathsBenchmark().report();
|
| + new RemoveBenchmark().report();
|
| +}
|
|
|