Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(450)

Side by Side Diff: runtime/lib/string_patch.dart

Issue 551823002: Optimize _GrowableArray._join and _StringBase._interpolate. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 patch class String { 5 patch class String {
6 /* patch */ factory String.fromCharCodes(Iterable<int> charCodes) { 6 /* patch */ factory String.fromCharCodes(Iterable<int> charCodes) {
7 return _StringBase.createFromCharCodes(charCodes); 7 return _StringBase.createFromCharCodes(charCodes);
8 } 8 }
9 9
10 /* patch */ factory String.fromCharCode(int charCode) { 10 /* patch */ factory String.fromCharCode(int charCode) {
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 int startIndex = 0; 511 int startIndex = 0;
512 for (Match match in pattern.allMatches(this)) { 512 for (Match match in pattern.allMatches(this)) {
513 buffer.write(onNonMatch(this.substring(startIndex, match.start))); 513 buffer.write(onNonMatch(this.substring(startIndex, match.start)));
514 buffer.write(onMatch(match).toString()); 514 buffer.write(onMatch(match).toString());
515 startIndex = match.end; 515 startIndex = match.end;
516 } 516 }
517 buffer.write(onNonMatch(this.substring(startIndex))); 517 buffer.write(onNonMatch(this.substring(startIndex)));
518 return buffer.toString(); 518 return buffer.toString();
519 } 519 }
520 520
521
522 /** 521 /**
523 * Convert all objects in [values] to strings and concat them 522 * Convert all objects in [values] to strings and concat them
524 * into a result string. 523 * into a result string.
524 * Modifies the input list if it contains non-`String` values.
525 */ 525 */
526 static String _interpolate(List<String> values) { 526 static String _interpolate(final List values) {
527 final numValues = values.length; 527 final numValues = values.length;
528 _List stringList = new List<String>(numValues); 528 if (numValues <= 2) {
529 bool isOneByteString = true; 529 // If possible, do this optimization at compiler level and call a
530 // specialized _interpolateSingle when there is only one argument,
531 // and _interpolateTwo with two.
532 // Call here only with three or more arguments.
533 // That would avoid allocating a list for the values if there are
534 // only one or two.
535 if (numValues == 0) return "";
536 final first = values[0];
537 final firstString = first.toString();
538 if (firstString is! String) {
539 throw new ArgumentError(first);
srdjan 2014/09/11 18:43:17 Use types for checked mode (final String firstStri
540 }
541 if (numValues == 1) return firstString;
542 final second = values[1];
543 final secondString = second.toString();
544 if (secondString is! String) {
545 throw new ArgumentError(second);
546 }
547 return firstString + secondString;
548 }
530 int totalLength = 0; 549 int totalLength = 0;
531 for (int i = 0; i < numValues; i++) { 550 for (int i = 0; i < numValues; i++) {
532 var s = values[i].toString(); 551 final e = values[i];
533 if (isOneByteString && (ClassID.getID(s) == ClassID.cidOneByteString)) { 552 final s = e.toString();
553 values[i] = s;
554 if (ClassID.getID(s) == ClassID.cidOneByteString) {
534 totalLength += s.length; 555 totalLength += s.length;
535 } else { 556 continue;
536 isOneByteString = false; 557 }
558 // Loops while the values convert to one-byte strings.
559 if (s is! String) {
560 throw new ArgumentError(s);
561 }
562 i++;
563 for (;i < numValues; i++) {
564 final e = values[i];
565 final s = e.toString();
566 values[i] = s;
537 if (s is! String) { 567 if (s is! String) {
538 throw new ArgumentError(s); 568 throw new ArgumentError(s);
539 } 569 }
540 } 570 }
541 stringList[i] = s; 571 return _concatRangeNative(values, 0, numValues);
542 } 572 }
543 if (isOneByteString) { 573 return _OneByteString._concatAll(values, totalLength);
544 return _OneByteString._concatAll(stringList, totalLength);
545 }
546 return _concatRangeNative(stringList, 0, stringList.length);
547 } 574 }
548 575
549 Iterable<Match> allMatches(String string, [int start = 0]) { 576 Iterable<Match> allMatches(String string, [int start = 0]) {
550 List<Match> result = new List<Match>(); 577 List<Match> result = new List<Match>();
551 int length = string.length; 578 int length = string.length;
552 int patternLength = this.length; 579 int patternLength = this.length;
553 int startIndex = start; 580 int startIndex = start;
554 while (true) { 581 while (true) {
555 int position = string.indexOf(this, startIndex); 582 int position = string.indexOf(this, startIndex);
556 if (position == -1) { 583 if (position == -1) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 int get hashCode native "String_getHashCode"; 681 int get hashCode native "String_getHashCode";
655 682
656 bool _isWhitespace(int codeUnit) { 683 bool _isWhitespace(int codeUnit) {
657 return _StringBase._isOneByteWhitespace(codeUnit); 684 return _StringBase._isOneByteWhitespace(codeUnit);
658 } 685 }
659 686
660 bool operator ==(Object other) { 687 bool operator ==(Object other) {
661 return super == other; 688 return super == other;
662 } 689 }
663 690
691 String operator +(String other) {
692 if (ClassID.getID(other) != ClassID.cidOneByteString) {
693 return super + other;
694 }
695 final thisLength = this.length;
696 final otherLength = other.length;
697 final length = thisLength + otherLength;
698 if (length > 128) {
699 final list = new _List(2);
700 list[0] = this;
701 list[1] = other;
702 return _concatAll(list, 0, 2);
703 }
704 final _OneByteString result = _allocate(length);
705 for (int i = 0; i < thisLength; i++) {
706 result._setAt(i, this.codeUnitAt(i));
707 }
708 for (int i = 0; i < otherLength; i++) {
709 result._setAt(thisLength + i, other.codeUnitAt(i));
710 }
711 return result;
712 }
713
664 String _substringUncheckedNative(int startIndex, int endIndex) 714 String _substringUncheckedNative(int startIndex, int endIndex)
665 native "OneByteString_substringUnchecked"; 715 native "OneByteString_substringUnchecked";
666 716
667 List<String> _splitWithCharCode(int charCode) 717 List<String> _splitWithCharCode(int charCode)
668 native "OneByteString_splitWithCharCode"; 718 native "OneByteString_splitWithCharCode";
669 719
670 List<String> split(Pattern pattern) { 720 List<String> split(Pattern pattern) {
671 if ((ClassID.getID(pattern) == ClassID.cidOneByteString) && 721 if ((ClassID.getID(pattern) == ClassID.cidOneByteString) &&
672 (pattern.length == 1)) { 722 (pattern.length == 1)) {
673 return _splitWithCharCode(pattern.codeUnitAt(0)); 723 return _splitWithCharCode(pattern.codeUnitAt(0));
674 } 724 }
675 return super.split(pattern); 725 return super.split(pattern);
676 } 726 }
677 727
678 // All element of 'strings' must be OneByteStrings. 728 // All element of 'strings' must be OneByteStrings.
679 static _concatAll(List<String> strings, int totalLength) { 729 static _concatAll(List<String> strings, int totalLength) {
680 // TODO(srdjan): Improve code below and raise or eliminate the limit. 730 // TODO(srdjan): Improve code below and raise or eliminate the limit.
681 if (totalLength > 128) { 731 if (totalLength > 128) {
682 // Native is quicker. 732 // Native is quicker.
683 return _StringBase._concatRangeNative(strings, 0, strings.length); 733 return _StringBase._concatRangeNative(strings, 0, strings.length);
684 } 734 }
685 var res = _OneByteString._allocate(totalLength); 735 final res = _OneByteString._allocate(totalLength);
686 final stringsLength = strings.length; 736 final stringsLength = strings.length;
687 int rIx = 0; 737 int rIx = 0;
688 for (int i = 0; i < stringsLength; i++) { 738 for (int i = 0; i < stringsLength; i++) {
689 _OneByteString e = strings[i]; 739 final _OneByteString e = strings[i];
690 final eLength = e.length; 740 final eLength = e.length;
691 for (int s = 0; s < eLength; s++) { 741 for (int s = 0; s < eLength; s++) {
692 res._setAt(rIx++, e.codeUnitAt(s)); 742 res._setAt(rIx++, e.codeUnitAt(s));
693 } 743 }
694 } 744 }
695 return res; 745 return res;
696 } 746 }
697 747
698 int indexOf(Pattern pattern, [int start = 0]) { 748 int indexOf(Pattern pattern, [int start = 0]) {
699 // Specialize for single character pattern. 749 // Specialize for single character pattern.
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 class _CodeUnits extends Object with ListMixin<int>, 1060 class _CodeUnits extends Object with ListMixin<int>,
1011 UnmodifiableListMixin<int> { 1061 UnmodifiableListMixin<int> {
1012 /** The string that this is the code units of. */ 1062 /** The string that this is the code units of. */
1013 String _string; 1063 String _string;
1014 1064
1015 _CodeUnits(this._string); 1065 _CodeUnits(this._string);
1016 1066
1017 int get length => _string.length; 1067 int get length => _string.length;
1018 int operator[](int i) => _string.codeUnitAt(i); 1068 int operator[](int i) => _string.codeUnitAt(i);
1019 } 1069 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698