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

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

Issue 42443002: Improve string library performance. String concat and indexOf. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month 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
« no previous file with comments | « runtime/lib/string_buffer_patch.dart ('k') | runtime/vm/bootstrap_natives.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 10
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 String operator +(String other) native "String_concat"; 77 String operator +(String other) native "String_concat";
78 78
79 String toString() { 79 String toString() {
80 return this; 80 return this;
81 } 81 }
82 82
83 bool operator ==(Object other) { 83 bool operator ==(Object other) {
84 if (identical(this, other)) { 84 if (identical(this, other)) {
85 return true; 85 return true;
86 } 86 }
87 if ((other is !String) || 87 // TODO(5413632): Compare hash codes when both are present.
Ivan Posva 2013/10/28 23:35:09 I don't think comparing hash codes is effective, a
srdjan 2013/10/29 17:02:29 Done.
88 if ((other is! String) ||
88 (this.length != other.length)) { 89 (this.length != other.length)) {
89 // TODO(5413632): Compare hash codes when both are present.
90 return false; 90 return false;
91 } 91 }
92 final len = this.length; 92 final int len = this.length;
Ivan Posva 2013/10/28 23:35:09 ?
srdjan 2013/10/29 17:02:29 Removed type.
93 for (int i = 0; i < len; i++) { 93 for (int i = 0; i < len; i++) {
94 if (this.codeUnitAt(i) != other.codeUnitAt(i)) { 94 if (this.codeUnitAt(i) != other.codeUnitAt(i)) {
95 return false; 95 return false;
96 } 96 }
97 } 97 }
98 return true; 98 return true;
99 } 99 }
100 100
101 101
102 int compareTo(String other) { 102 int compareTo(String other) {
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 isOneByteString = false; 417 isOneByteString = false;
418 if (s is! String) { 418 if (s is! String) {
419 throw new ArgumentError(s); 419 throw new ArgumentError(s);
420 } 420 }
421 } 421 }
422 stringList[i] = s; 422 stringList[i] = s;
423 } 423 }
424 if (isOneByteString) { 424 if (isOneByteString) {
425 return _OneByteString._concatAll(stringList, totalLength); 425 return _OneByteString._concatAll(stringList, totalLength);
426 } 426 }
427 return _concatAllNative(stringList, 0, stringList.length); 427 return _concatRangeNative(stringList, 0, stringList.length);
428 } 428 }
429 429
430 Iterable<Match> allMatches(String str) { 430 Iterable<Match> allMatches(String str) {
431 List<Match> result = new List<Match>(); 431 List<Match> result = new List<Match>();
432 int length = str.length; 432 int length = str.length;
433 int patternLength = this.length; 433 int patternLength = this.length;
434 int startIndex = 0; 434 int startIndex = 0;
435 while (true) { 435 while (true) {
436 int position = str.indexOf(this, startIndex); 436 int position = str.indexOf(this, startIndex);
437 if (position == -1) { 437 if (position == -1) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 } 502 }
503 503
504 List<int> get codeUnits => new _CodeUnits(this); 504 List<int> get codeUnits => new _CodeUnits(this);
505 505
506 Runes get runes => new Runes(this); 506 Runes get runes => new Runes(this);
507 507
508 String toUpperCase() native "String_toUpperCase"; 508 String toUpperCase() native "String_toUpperCase";
509 509
510 String toLowerCase() native "String_toLowerCase"; 510 String toLowerCase() native "String_toLowerCase";
511 511
512 // Concatenate ['start', 'end'[ elements of 'strings'. 'strings' must contain
513 // String elements. Optimized for OneByteStrings.
514 static String _concatRange(List<String> strings, int start, int end) {
515 if ((end - start) == 1) {
516 return strings[start];
517 }
518 final int numValues = strings.length;
519 if (start == 0 && (end == numValues)) {
Ivan Posva 2013/10/28 23:35:09 (start == 0)
srdjan 2013/10/29 17:02:29 Done.
520 int totalLength = 0;
521 for (int i = 0; i < numValues; i++) {
522 String s = strings[i];
523 if (s._cid != _OneByteString._classId) {
524 return _concatRangeNative(strings, start, end);
525 }
526 totalLength += s.length;
527 }
528 return _OneByteString._concatAll(strings, totalLength);
529 }
530 return _concatRangeNative(strings, start, end);
531 }
532
512 // Call this method if not all list elements are known to be OneByteString(s). 533 // Call this method if not all list elements are known to be OneByteString(s).
513 // 'strings' must be an _List or _GrowableList. 534 // 'strings' must be an _List or _GrowableList.
514 static String _concatAllNative(List<String> strings, int start, int end) 535 static String _concatRangeNative(List<String> strings, int start, int end)
515 native "Strings_concatAll"; 536 native "String_concatRange";
516 } 537 }
517 538
518 539
519 class _OneByteString extends _StringBase implements String { 540 class _OneByteString extends _StringBase implements String {
520 static final int _classId = "A"._cid; 541 static final int _classId = "A"._cid;
521 542
522 factory _OneByteString._uninstantiable() { 543 factory _OneByteString._uninstantiable() {
523 throw new UnsupportedError( 544 throw new UnsupportedError(
524 "_OneByteString can only be allocated by the VM"); 545 "_OneByteString can only be allocated by the VM");
525 } 546 }
(...skipping 15 matching lines...) Expand all
541 native "OneByteString_splitWithCharCode"; 562 native "OneByteString_splitWithCharCode";
542 563
543 List<String> split(Pattern pattern) { 564 List<String> split(Pattern pattern) {
544 if ((pattern._cid == _OneByteString._classId) && (pattern.length == 1)) { 565 if ((pattern._cid == _OneByteString._classId) && (pattern.length == 1)) {
545 return _splitWithCharCode(pattern.codeUnitAt(0)); 566 return _splitWithCharCode(pattern.codeUnitAt(0));
546 } 567 }
547 return super.split(pattern); 568 return super.split(pattern);
548 } 569 }
549 570
550 // All element of 'strings' must be OneByteStrings. 571 // All element of 'strings' must be OneByteStrings.
551 static _concatAll(_List<String> strings, int totalLength) { 572 static _concatAll(List<String> strings, int totalLength) {
552 // TODO(srdjan): Improve code below and raise or eliminate the limit. 573 // TODO(srdjan): Improve code below and raise or eliminate the limit.
553 if (totalLength > 128) { 574 if (totalLength > 128) {
554 // Native is quicker. 575 // Native is quicker.
555 return _StringBase._concatAllNative(strings, 0, strings.length); 576 return _StringBase._concatRangeNative(strings, 0, strings.length);
556 } 577 }
557 var res = _OneByteString._allocate(totalLength); 578 var res = _OneByteString._allocate(totalLength);
558 final stringsLength = strings.length; 579 final stringsLength = strings.length;
559 int rIx = 0; 580 int rIx = 0;
560 for (int i = 0; i < stringsLength; i++) { 581 for (int i = 0; i < stringsLength; i++) {
561 _OneByteString e = strings[i]; 582 _OneByteString e = strings[i];
562 final eLength = e.length; 583 final eLength = e.length;
563 for (int s = 0; s < eLength; s++) { 584 for (int s = 0; s < eLength; s++) {
564 res._setAt(rIx++, e.codeUnitAt(s)); 585 res._setAt(rIx++, e.codeUnitAt(s));
565 } 586 }
566 } 587 }
567 return res; 588 return res;
568 } 589 }
569 590
591 int indexOf(Pattern pattern, [int start = 0]) {
592 final int len = this.length;
Ivan Posva 2013/10/28 23:35:09 Not sure whether we should be using this. or not.
srdjan 2013/10/29 17:02:29 The name' length' is too generic, therefore I feel
593 // Specialize for single character pattern.
594 if ((pattern._cid == _OneByteString._classId) &&
Ivan Posva 2013/10/28 23:35:09 What about an ExternalOneByteString?
srdjan 2013/10/29 17:02:29 Added: TODO. The inner loop should stay monomorphi
595 (pattern.length == 1) &&
596 (start >= 0) && (start < len)) {
597 final int patternCu0 = pattern.codeUnitAt(0);
Ivan Posva 2013/10/28 23:35:09 Another quick test you could do: If the pattern is
srdjan 2013/10/29 17:02:29 Good idea, once I allow two byte strings.
598 for (int i = start; i < len; i++) {
599 if (this.codeUnitAt(i) == patternCu0) {
600 return i;
601 }
602 }
603 return -1;
604 }
605 return super.indexOf(pattern, start);
606 }
607
570 // Allocates a string of given length, expecting its content to be 608 // Allocates a string of given length, expecting its content to be
571 // set using _setAt. 609 // set using _setAt.
572 static _OneByteString _allocate(int length) native "OneByteString_allocate"; 610 static _OneByteString _allocate(int length) native "OneByteString_allocate";
573 611
574 // This is internal helper method. Code point value must be a valid 612 // This is internal helper method. Code point value must be a valid
575 // Latin1 value (0..0xFF), index must be valid. 613 // Latin1 value (0..0xFF), index must be valid.
576 void _setAt(int index, int codePoint) native "OneByteString_setAt"; 614 void _setAt(int index, int codePoint) native "OneByteString_setAt";
577 } 615 }
578 616
579 617
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 class _CodeUnits extends Object with ListMixin<int>, 698 class _CodeUnits extends Object with ListMixin<int>,
661 UnmodifiableListMixin<int> { 699 UnmodifiableListMixin<int> {
662 /** The string that this is the code units of. */ 700 /** The string that this is the code units of. */
663 String _string; 701 String _string;
664 702
665 _CodeUnits(this._string); 703 _CodeUnits(this._string);
666 704
667 int get length => _string.length; 705 int get length => _string.length;
668 int operator[](int i) => _string.codeUnitAt(i); 706 int operator[](int i) => _string.codeUnitAt(i);
669 } 707 }
OLDNEW
« no previous file with comments | « runtime/lib/string_buffer_patch.dart ('k') | runtime/vm/bootstrap_natives.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698