| // Copyright (c) 2021, 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. |
| |
| // @dart=2.9 |
| |
| import 'dart:async'; |
| import 'dart:convert'; |
| import 'dart:isolate'; |
| |
| // (Same data as used in our other Json* benchmarks) |
| final data = '{"summary":{"turnover":0.3736,"correlation2":0.' |
| '7147,"concentration":0.3652,"beta":0.8814,"totalValue":1.3' |
| '091078259E8,"correlation":0.7217},"watchlist":[],"shortCash' |
| '":-1611000,"holdings":[{"type":"LONG","commission":1040' |
| ',"cost":9001920,"quantity":26000,"lots":[{"marketCap":"' |
| 'L","industry":"TECHNOLOGY","style":"G","buyDate":"20' |
| '08-10-08 13:44:20.000","quantity":8000},{"marketCap":"L",' |
| '"industry":"TECHNOLOGY","style":"G","buyDate":"2008-1' |
| '0-15 13:28:02.000","quantity":18000}],"stock":"GOOG"},{"' |
| 'type":"LONG","commission":8000,"cost":4672000,"quantity' |
| '":200000,"lots":[{"marketCap":"L","industry":"TECHNOLO' |
| 'GY","style":"G","buyDate":"2008-10-15 13:28:54.000","q' |
| 'uantity":200000}],"stock":"MSFT"},{"type":"LONG","comm' |
| 'ission":21877,"cost":1.001592313E7,"quantity":546919,"lots' |
| '":[{"marketCap":"L","industry":"FINANCIAL","style":"' |
| 'G","buyDate":"2008-08-01 09:50:17.000","quantity":103092}' |
| ',{"marketCap":"L","industry":"FINANCIAL","style":"G"' |
| ',"buyDate":"2008-08-18 10:31:34.000","quantity":49950},{"' |
| 'marketCap":"L","industry":"FINANCIAL","style":"G","b' |
| 'uyDate":"2008-08-29 09:35:22.000","quantity":45045},{"mark' |
| 'etCap":"L","industry":"FINANCIAL","style":"G","buyDa' |
| 'te":"2008-09-15 09:40:32.000","quantity":48400},{"marketCa' |
| 'p":"L","industry":"FINANCIAL","style":"G","buyDate"' |
| ':"2008-10-06 11:21:50.000","quantity":432},{"marketCap":"' |
| 'L","industry":"FINANCIAL","style":"G","buyDate":"200' |
| '8-10-15 13:30:05.000","quantity":300000}],"stock":"UBS"},' |
| '{"type":"LONG","commission":4000,"cost":6604849.1,"quan' |
| 'tity":122741,"lots":[{"marketCap":"L","industry":"SERV' |
| 'ICES","style":"V","buyDate":"2008-04-26 04:44:34.000",' |
| '"quantity":22741},{"marketCap":"L","industry":"SERVICES' |
| '","style":"V","buyDate":"2008-10-15 13:31:02.000","qua' |
| 'ntity":100000}],"stock":"V"},{"type":"LONG","commissio' |
| 'n":2805,"cost":5005558.25,"quantity":70121,"lots":[{"mar' |
| 'ketCap":"M","industry":"RETAIL","style":"G","buyDate' |
| '":"2008-10-10 10:48:36.000","quantity":121},{"marketCap":' |
| '"M","industry":"RETAIL","style":"G","buyDate":"2008' |
| '-10-15 13:33:44.000","quantity":70000}],"stock":"LDG"},{' |
| '"type":"LONG","commission":10000,"cost":5382500,"quanti' |
| 'ty":250000,"lots":[{"marketCap":"L","industry":"RETAIL' |
| '","style":"V","buyDate":"2008-10-15 13:34:30.000","qua' |
| 'ntity":250000}],"stock":"SWY"},{"type":"LONG","commiss' |
| 'ion":1120,"cost":1240960,"quantity":28000,"lots":[{"mark' |
| 'etCap":"u","industry":"ETF","style":"B","buyDate":' |
| '"2008-10-15 15:57:39.000","quantity":28000}],"stock":"OIL' |
| '"},{"type":"LONG","commission":400,"cost":236800,"quan' |
| 'tity":10000,"lots":[{"marketCap":"M","industry":"UTILI' |
| 'TIES_AND_ENERGY","style":"G","buyDate":"2008-10-15 15:58' |
| ':03.000","quantity":10000}],"stock":"COG"},{"type":"LO' |
| 'NG","commission":3200,"cost":1369600,"quantity":80000,"l' |
| 'ots":[{"marketCap":"S","industry":"UTILITIES_AND_ENERGY' |
| '","style":"G","buyDate":"2008-10-15 15:58:32.000","qua' |
| 'ntity":80000}],"stock":"CRZO"},{"type":"LONG","commiss' |
| 'ion":429,"cost":108164.8,"quantity":10720,"lots":[{"mark' |
| 'etCap":"u","industry":"FINANCIAL","style":"V","buyDa' |
| 'te":"2008-10-16 09:37:06.000","quantity":10720}],"stock":' |
| '"FGI"},{"type":"LONG","commission":1080,"cost":494910,' |
| '"quantity":27000,"lots":[{"marketCap":"L","industry":' |
| '"RETAIL","style":"V","buyDate":"2008-10-16 09:37:06.000' |
| '","quantity":27000}],"stock":"LOW"},{"type":"LONG","' |
| 'commission":4080,"cost":4867440,"quantity":102000,"lots":' |
| '[{"marketCap":"L","industry":"HEALTHCARE","style":"V' |
| '","buyDate":"2008-10-16 09:37:06.000","quantity":102000}]' |
| ',"stock":"AMGN"},{"type":"SHORT","commission":4000,"' |
| 'cost":-1159000,"quantity":-100000,"lots":[{"marketCap":' |
| '"L","industry":"TECHNOLOGY","style":"V","buyDate":' |
| '"2008-10-16 09:37:06.000","quantity":-100000}],"stock":"' |
| 'AMAT"},{"type":"LONG","commission":2,"cost":5640002,"' |
| 'quantity":50,"lots":[{"marketCap":"L","industry":"FIN' |
| 'ANCIAL","style":"B","buyDate":"2008-10-16 09:37:06.000' |
| '","quantity":50}],"stock":"BRKA"},{"type":"SHORT","' |
| 'commission":4000,"cost":-436000,"quantity":-100000,"lots' |
| '":[{"marketCap":"M","industry":"TRANSPORTATION","styl' |
| 'e":"G","buyDate":"2008-10-16 09:37:06.000","quantity":-' |
| '100000}],"stock":"JBLU"},{"type":"LONG","commission":8' |
| '000,"cost":1.1534E7,"quantity":200000,"lots":[{"marketCap' |
| '":"S","industry":"FINANCIAL","style":"G","buyDate":' |
| '"2008-10-16 14:35:24.000","quantity":200000}],"stock":"US' |
| 'O"},{"type":"LONG","commission":4000,"cost":1.0129E7,"' |
| 'quantity":100000,"lots":[{"marketCap":"L","industry":"' |
| 'TECHNOLOGY","style":"G","buyDate":"2008-10-15 13:28:26.0' |
| '00","quantity":50000},{"marketCap":"L","industry":"TEC' |
| 'HNOLOGY","style":"G","buyDate":"2008-10-17 09:33:09.000' |
| '","quantity":50000}],"stock":"AAPL"},{"type":"LONG",' |
| '"commission":1868,"cost":9971367.2,"quantity":54280,"lots' |
| '":[{"marketCap":"L","industry":"SERVICES","style":"G' |
| '","buyDate":"2008-04-26 04:44:34.000","quantity":7580},{' |
| '"marketCap":"L","industry":"SERVICES","style":"G","' |
| 'buyDate":"2008-05-29 09:50:28.000","quantity":7500},{"mark' |
| 'etCap":"L","industry":"SERVICES","style":"G","buyDat' |
| 'e":"2008-10-15 13:30:38.000","quantity":33000},{"marketCap' |
| '":"L","industry":"SERVICES","style":"G","buyDate":' |
| '"2008-10-17 09:33:09.000","quantity":6200}],"stock":"MA"' |
| '}],"longCash":4.600368106E7,"ownerId":8,"pendingOrders":[{' |
| '"total":487000,"type":"cover","subtotal":483000,"price' |
| '":4.83,"commission":4000,"date":"2008-10-17 23:56:06.000"' |
| ',"quantity":100000,"expires":"2008-10-20 16:00:00.000","s' |
| 'tock":"JBLU","id":182375},{"total":6271600,"type":"buy' |
| '","subtotal":6270000,"price":156.75,"commission":1600,"d' |
| 'ate":"2008-10-17 23:56:40.000","quantity":40000,"expires"' |
| ':"2008-10-20 16:00:00.000","stock":"MA","id":182376}],"' |
| 'inceptionDate":"2008-04-26 04:44:29.000","withdrawals":0,"' |
| 'id":219948,"deposits":0}'; |
| |
| class SendPortBenchmark { |
| final BenchmarkConfig config; |
| ReceivePort port; |
| StreamIterator it; |
| |
| double usPerSend = 0.0; |
| double usPerReceive = 0.0; |
| |
| SendPortBenchmark(this.config); |
| |
| // Runs warmup phase, runs benchmark and reports result. |
| Future report() async { |
| port = ReceivePort(); |
| it = StreamIterator(port); |
| |
| // Warmup for 100 ms. |
| await measureFor(const Duration(milliseconds: 200)); |
| |
| // Run benchmark for 2 seconds. |
| // |
| // Sets [usPerSend] and [usPerReceive] as side-effect. |
| await measureFor(const Duration(seconds: 2)); |
| |
| // Report result. |
| print('SendPort.Send.${config.name}(RunTimeRaw): $usPerSend us.'); |
| print('SendPort.Receive.${config.name}(RunTimeRaw): $usPerReceive us.'); |
| |
| await it.cancel(); |
| port.close(); |
| } |
| |
| Future measureFor(Duration duration) async { |
| final durationInMicroseconds = duration.inMicroseconds; |
| |
| int sumSendUs = 0; |
| int sumReceiveUs = 0; |
| |
| final sw = Stopwatch()..start(); |
| |
| int numberOfSendReceives = 0; |
| int lastUs = 0; |
| int currentUs = 0; |
| do { |
| // Send & measure time |
| port.sendPort.send(config.data); |
| currentUs = sw.elapsedMicroseconds; |
| sumSendUs += currentUs - lastUs; |
| lastUs = currentUs; |
| |
| // Receive & measure time |
| await it.moveNext(); |
| it.current; |
| currentUs = sw.elapsedMicroseconds; |
| sumReceiveUs += currentUs - lastUs; |
| lastUs = currentUs; |
| |
| numberOfSendReceives++; |
| } while (lastUs < durationInMicroseconds); |
| |
| usPerSend = sumSendUs / numberOfSendReceives; |
| usPerReceive = sumReceiveUs / numberOfSendReceives; |
| } |
| } |
| |
| class TreeNode { |
| @pragma('vm:entry-point') // Prevent tree shaking of this field. |
| final TreeNode left; |
| @pragma('vm:entry-point') // Prevent tree shaking of this field. |
| final TreeNode right; |
| @pragma('vm:entry-point') // Prevent tree shaking of this field. |
| final int value; |
| |
| TreeNode(this.left, this.right, this.value); |
| } |
| |
| TreeNode generateBinaryTreeOfDepth(int depth) { |
| int i = 0; |
| |
| TreeNode gen(int depth) { |
| if (depth == 0) return TreeNode(null, null, i++); |
| return TreeNode(gen(depth - 1), gen(depth - 1), i++); |
| } |
| |
| return gen(depth); |
| } |
| |
| class BenchmarkConfig { |
| final String name; |
| final dynamic data; |
| |
| BenchmarkConfig(this.name, this.data); |
| } |
| |
| Future<void> main(args) async { |
| final String json5KB = data; |
| final json5KBDecoded = json.decode(json5KB); |
| assert(json5KB.length == 5534); |
| |
| final json400B = json.encode(json5KBDecoded['pendingOrders']); |
| final json400BDecoded = json.decode(json400B); |
| assert(json400B.length == 390); |
| |
| final String json50KB = json.encode({ |
| '1': [json5KBDecoded, json5KBDecoded, json5KBDecoded, json5KBDecoded], |
| '2': [json5KBDecoded, json5KBDecoded, json5KBDecoded, json5KBDecoded], |
| '3': json5KBDecoded, |
| }); |
| final json50KBDecoded = json.decode(json50KB); |
| assert(json50KB.length == 49814); |
| |
| final String json500KB = json.encode({ |
| '1': [json50KBDecoded, json50KBDecoded, json50KBDecoded, json50KBDecoded], |
| '2': [json50KBDecoded, json50KBDecoded, json50KBDecoded, json50KBDecoded], |
| '3': [json50KBDecoded, json50KBDecoded], |
| }); |
| final json500KBDecoded = json.decode(json500KB); |
| assert(json500KB.length == 498169); |
| |
| final String json5MB = json.encode({ |
| '1': [ |
| json500KBDecoded, |
| json500KBDecoded, |
| json500KBDecoded, |
| ], |
| '2': [json500KBDecoded, json500KBDecoded, json500KBDecoded], |
| '3': [json500KBDecoded, json500KBDecoded, json500KBDecoded], |
| '4': json500KBDecoded, |
| }); |
| final json5MBDecoded = json.decode(json5MB); |
| assert(json5MB.length == 4981723); |
| |
| final configs = <BenchmarkConfig>[ |
| BenchmarkConfig('Nop', 1), |
| BenchmarkConfig('Json.400B', json400BDecoded), |
| BenchmarkConfig('Json.5KB', json5KBDecoded), |
| BenchmarkConfig('Json.50KB', json50KBDecoded), |
| BenchmarkConfig('Json.500KB', json500KBDecoded), |
| BenchmarkConfig('Json.5MB', json5MBDecoded), |
| BenchmarkConfig('BinaryTree.2', generateBinaryTreeOfDepth(2)), |
| BenchmarkConfig('BinaryTree.4', generateBinaryTreeOfDepth(4)), |
| BenchmarkConfig('BinaryTree.6', generateBinaryTreeOfDepth(6)), |
| BenchmarkConfig('BinaryTree.8', generateBinaryTreeOfDepth(8)), |
| BenchmarkConfig('BinaryTree.10', generateBinaryTreeOfDepth(10)), |
| BenchmarkConfig('BinaryTree.12', generateBinaryTreeOfDepth(12)), |
| BenchmarkConfig('BinaryTree.14', generateBinaryTreeOfDepth(14)), |
| ]; |
| |
| for (final config in configs) { |
| await SendPortBenchmark(config).report(); |
| } |
| } |