OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 /// Benchmarks for the PathSet class. |
| 6 library watcher.benchmark.path_set; |
| 7 |
| 8 import 'dart:io'; |
| 9 import 'dart:math' as math; |
| 10 |
| 11 import 'package:benchmark_harness/benchmark_harness.dart'; |
| 12 import 'package:path/path.dart' as p; |
| 13 |
| 14 import 'package:watcher/src/path_set.dart'; |
| 15 |
| 16 final String root = Platform.isWindows ? r"C:\root" : "/root"; |
| 17 |
| 18 /// Base class for benchmarks on [PathSet]. |
| 19 abstract class PathSetBenchmark extends BenchmarkBase { |
| 20 PathSetBenchmark(String method) : super("PathSet.$method"); |
| 21 |
| 22 final PathSet pathSet = new PathSet(root); |
| 23 |
| 24 /// Use a fixed [Random] with a constant seed to ensure the tests are |
| 25 /// deterministic. |
| 26 final math.Random random = new math.Random(1234); |
| 27 |
| 28 /// Walks over a virtual directory [depth] levels deep invoking [callback] |
| 29 /// for each "file". |
| 30 /// |
| 31 /// Each virtual directory contains ten entries: either subdirectories or |
| 32 /// files. |
| 33 void walkTree(int depth, callback(String path)) { |
| 34 recurse(path, remainingDepth) { |
| 35 for (var i = 0; i < 10; i++) { |
| 36 var padded = i.toString().padLeft(2, '0'); |
| 37 if (remainingDepth == 0) { |
| 38 callback(p.join(path, "file_$padded.txt")); |
| 39 } else { |
| 40 var subdir = p.join(path, "subdirectory_$padded"); |
| 41 recurse(subdir, remainingDepth - 1); |
| 42 } |
| 43 } |
| 44 } |
| 45 |
| 46 recurse(root, depth); |
| 47 } |
| 48 } |
| 49 |
| 50 class AddBenchmark extends PathSetBenchmark { |
| 51 AddBenchmark() : super("add()"); |
| 52 |
| 53 final List<String> paths = []; |
| 54 |
| 55 void setup() { |
| 56 // Make a bunch of paths in about the same order we expect to get them from |
| 57 // Directory.list(). |
| 58 walkTree(3, paths.add); |
| 59 } |
| 60 |
| 61 void run() { |
| 62 for (var path in paths) pathSet.add(path); |
| 63 } |
| 64 } |
| 65 |
| 66 class ContainsBenchmark extends PathSetBenchmark { |
| 67 ContainsBenchmark() : super("contains()"); |
| 68 |
| 69 final List<String> paths = []; |
| 70 |
| 71 void setup() { |
| 72 // Add a bunch of paths to the set. |
| 73 walkTree(3, (path) { |
| 74 pathSet.add(path); |
| 75 paths.add(path); |
| 76 }); |
| 77 |
| 78 // Add some non-existent paths to test the false case. |
| 79 for (var i = 0; i < 100; i++) { |
| 80 paths.addAll([ |
| 81 "/nope", |
| 82 "/root/nope", |
| 83 "/root/subdirectory_04/nope", |
| 84 "/root/subdirectory_04/subdirectory_04/nope", |
| 85 "/root/subdirectory_04/subdirectory_04/subdirectory_04/nope", |
| 86 "/root/subdirectory_04/subdirectory_04/subdirectory_04/nope/file_04.txt"
, |
| 87 ]); |
| 88 } |
| 89 } |
| 90 |
| 91 void run() { |
| 92 var contained = 0; |
| 93 for (var path in paths) { |
| 94 if (pathSet.contains(path)) contained++; |
| 95 } |
| 96 |
| 97 if (contained != 10000) throw "Wrong result: $contained"; |
| 98 } |
| 99 } |
| 100 |
| 101 class PathsBenchmark extends PathSetBenchmark { |
| 102 PathsBenchmark() : super("toSet()"); |
| 103 |
| 104 void setup() { |
| 105 walkTree(3, pathSet.add); |
| 106 } |
| 107 |
| 108 void run() { |
| 109 var count = 0; |
| 110 for (var _ in pathSet.paths) { |
| 111 count++; |
| 112 } |
| 113 |
| 114 if (count != 10000) throw "Wrong result: $count"; |
| 115 } |
| 116 } |
| 117 |
| 118 class RemoveBenchmark extends PathSetBenchmark { |
| 119 RemoveBenchmark() : super("remove()"); |
| 120 |
| 121 final List<String> paths = []; |
| 122 |
| 123 void setup() { |
| 124 // Make a bunch of paths. Do this here so that we don't spend benchmarked |
| 125 // time synthesizing paths. |
| 126 walkTree(3, (path) { |
| 127 pathSet.add(path); |
| 128 paths.add(path); |
| 129 }); |
| 130 |
| 131 // Shuffle the paths so that we delete them in a random order that |
| 132 // hopefully mimics real-world file system usage. Do the shuffling here so |
| 133 // that we don't spend benchmarked time shuffling. |
| 134 paths.shuffle(random); |
| 135 } |
| 136 |
| 137 void run() { |
| 138 for (var path in paths) pathSet.remove(path); |
| 139 } |
| 140 } |
| 141 |
| 142 main() { |
| 143 new AddBenchmark().report(); |
| 144 new ContainsBenchmark().report(); |
| 145 new PathsBenchmark().report(); |
| 146 new RemoveBenchmark().report(); |
| 147 } |
OLD | NEW |