OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013, 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 library observe.test.benchmark.setup_observation_benchmark_base; | |
5 | |
6 import 'dart:async'; | |
7 import 'dart:html'; | |
8 import 'package:observe/observe.dart'; | |
9 import 'package:benchmark_harness/benchmark_harness.dart'; | |
10 | |
11 abstract class SetupObservationBenchmarkBase extends BenchmarkBase { | |
12 /// The number of objects to create and observe. | |
13 final int objectCount; | |
14 | |
15 /// The current configuration. | |
16 final String config; | |
17 | |
18 /// The objects we want to observe. | |
19 List<Observable> objects; | |
20 | |
21 SetupObservationBenchmarkBase(String name, this.objectCount, this.config) | |
22 : super(name); | |
23 | |
24 /// Subclasses should use this method to return an observable object to be | |
25 /// benchmarked. | |
26 Observable newObject(); | |
27 | |
28 /// Subclasses should override this to do anything other than a default change | |
29 /// listener. It must return either a StreamSubscription or a PathObserver. | |
30 newObserver(obj) => obj.changes.listen((_) {}); | |
31 | |
32 /// Set up each benchmark by creating all the objects. | |
33 @override | |
34 void setup() { | |
35 objects = []; | |
36 while (objects.length < objectCount) { | |
37 objects.add(newObject()); | |
38 } | |
39 } | |
40 | |
41 /// Tear down each the benchmark and remove all listeners. | |
42 @override | |
43 void teardown() { | |
44 while (objects.isNotEmpty) { | |
45 var obj = objects.removeLast(); | |
46 if (obj.hasObservers || (obj is ObservableList && obj.hasListObservers)) { | |
47 window.alert('Observers leaked!'); | |
48 } | |
49 } | |
50 objects = null; | |
51 } | |
52 | |
53 /// Run the benchmark by creating a listener on each object. | |
54 @override | |
55 void run() { | |
56 for (var object in objects) { | |
57 var observer = newObserver(object); | |
58 | |
59 // **Note:** This is different than the JS implementation. Since run can | |
60 // be called an arbitrary number of times between [setup] and [teardown], | |
61 // we clean up all observers as we go. This means we are measuring both | |
62 // the setup and teardown of observers, versus the setup only in the | |
63 // JS benchmark. Not cleaning these up ends up giving `oh snap` errors. | |
64 if (observer is StreamSubscription) { | |
65 observer.cancel(); | |
66 } else if (observer is PathObserver) { | |
67 observer.close(); | |
68 } else { | |
69 throw 'Unknown observer type ${observer.runtimeType}. Only ' | |
70 '[PathObserver] and [StreamSubscription] are supported.'; | |
71 } | |
72 } | |
73 } | |
74 } | |
OLD | NEW |