| // Copyright (c) 2014, 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. |
| |
| /** |
| * Overall performance of a code completion operation. |
| */ |
| class CompletionPerformance { |
| final DateTime start = new DateTime.now(); |
| final Map<String, Duration> _startTimes = new Map<String, Duration>(); |
| final Stopwatch _stopwatch = new Stopwatch(); |
| final List<OperationPerformance> operations = <OperationPerformance>[]; |
| |
| String path; |
| String snippet = ''; |
| int notificationCount = -1; |
| int suggestionCountFirst = -1; |
| int suggestionCountLast = -1; |
| Duration _firstNotification; |
| |
| CompletionPerformance() { |
| _stopwatch.start(); |
| } |
| |
| int get elapsedInMilliseconds => |
| operations.isNotEmpty ? operations.last.elapsed.inMilliseconds : 0; |
| |
| String get suggestionCount { |
| if (notificationCount < 1) return ''; |
| if (notificationCount == 1) return '$suggestionCountFirst'; |
| return '$suggestionCountFirst, $suggestionCountLast'; |
| } |
| |
| void complete([String tag = null]) { |
| _stopwatch.stop(); |
| _logDuration(tag ?? 'total time', _stopwatch.elapsed); |
| } |
| |
| void logElapseTime(String tag) { |
| Duration end = _stopwatch.elapsed; |
| Duration start = _startTimes[tag]; |
| if (start == null) { |
| _logDuration(tag, null); |
| return null; |
| } |
| _logDuration(tag, end - start); |
| } |
| |
| void logFirstNotificationComplete(String tag) { |
| _firstNotification = _stopwatch.elapsed; |
| _logDuration(tag, _firstNotification); |
| } |
| |
| void logStartTime(String tag) { |
| _startTimes[tag] = _stopwatch.elapsed; |
| } |
| |
| void setContentsAndOffset(String contents, int offset) { |
| snippet = _computeSnippet(contents, offset); |
| } |
| |
| void _logDuration(String tag, Duration elapsed) { |
| operations.add(new OperationPerformance(tag, elapsed)); |
| } |
| |
| static String _computeSnippet(String contents, int offset) { |
| if (contents == null || |
| offset == null || |
| offset < 0 || |
| contents.length < offset) { |
| return '???'; |
| } |
| int start = offset; |
| while (start > 0) { |
| String ch = contents[start - 1]; |
| if (ch == '\r' || ch == '\n') { |
| break; |
| } |
| --start; |
| } |
| int end = offset; |
| while (end < contents.length) { |
| String ch = contents[end]; |
| if (ch == '\r' || ch == '\n') { |
| break; |
| } |
| ++end; |
| } |
| String prefix = contents.substring(start, offset); |
| String suffix = contents.substring(offset, end); |
| return '$prefix^$suffix'; |
| } |
| } |
| |
| /** |
| * The performance of an operation when computing code completion. |
| */ |
| class OperationPerformance { |
| /** |
| * The name of the operation |
| */ |
| final String name; |
| |
| /** |
| * The elapse time or `null` if undefined. |
| */ |
| final Duration elapsed; |
| |
| OperationPerformance(this.name, this.elapsed); |
| } |