| // Copyright (c) 2022, 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. |
| // |
| // Measures performance of RegExp reuse between isolates. |
| |
| import 'dart:async'; |
| import 'dart:isolate'; |
| |
| import 'package:benchmark_harness/benchmark_harness.dart'; |
| |
| class SendReceiveRegExp extends AsyncBenchmarkBase { |
| SendReceiveRegExp(String name, this.re) : super(name); |
| |
| @override |
| Future<void> run() async { |
| await helper.run(re); |
| } |
| |
| @override |
| Future<void> setup() async { |
| helper = SendReceiveHelper(); |
| await helper.setup(); |
| } |
| |
| @override |
| Future<void> teardown() async { |
| await helper.finalize(); |
| } |
| |
| late SendReceiveHelper helper; |
| RegExp re; |
| } |
| |
| class SendReceiveHelper { |
| SendReceiveHelper(); |
| |
| Future<void> setup() async { |
| final port = ReceivePort(); |
| inbox = StreamIterator<dynamic>(port); |
| workerExitedPort = ReceivePort(); |
| await Isolate.spawn(isolate, port.sendPort, |
| onExit: workerExitedPort.sendPort); |
| await inbox.moveNext(); |
| outbox = inbox.current; |
| } |
| |
| Future<void> finalize() async { |
| outbox.send(null); |
| await workerExitedPort.first; |
| workerExitedPort.close(); |
| await inbox.cancel(); |
| } |
| |
| // Send regexp to worker, get one back, repeat few times. |
| Future<void> run(RegExp re) async { |
| for (int i = 0; i < 5; i++) { |
| outbox.send(re); |
| await inbox.moveNext(); |
| re = inbox.current; |
| } |
| } |
| |
| late StreamIterator<dynamic> inbox; |
| late SendPort outbox; |
| late ReceivePort workerExitedPort; |
| } |
| |
| Future<void> isolate(SendPort sendPort) async { |
| final port = ReceivePort(); |
| final inbox = StreamIterator<dynamic>(port); |
| |
| sendPort.send(port.sendPort); |
| while (true) { |
| await inbox.moveNext(); |
| final received = inbox.current; |
| if (received == null) { |
| break; |
| } |
| // use RegExp to ensure it is compiled |
| final RegExp re = received as RegExp; |
| re.firstMatch('h' * 1000); |
| // send the RegExp |
| sendPort.send(re); |
| } |
| port.close(); |
| } |
| |
| Future<void> main() async { |
| await SendReceiveRegExp('IsolateRegExp.MatchFast', RegExp('h?h')).report(); |
| await SendReceiveRegExp('IsolateRegExp.MatchSlow', |
| RegExp(r'(?<=\W|\b|^)(a.? b c.?) ?(\(.*\))?$')) |
| .report(); |
| } |