@@ -703,18 +703,48 @@ class Builder {
703
703
}
704
704
705
705
int _writeString (String value) {
706
- // TODO(scheglov) optimize for ASCII strings
707
- List <int > bytes = utf8.encode (value);
708
- int length = bytes.length;
706
+ // [utf8.encode()] is slow (up to at least Dart SDK 2.13). If the given
707
+ // string is ASCII we can just write it directly, without any conversion.
708
+ final originalTail = _tail;
709
+ if (! _tryWriteASCIIString (value)) {
710
+ // reset the output buffer position for [_writeUTFString()]
711
+ _tail = originalTail;
712
+ _writeUTFString (value);
713
+ }
714
+ return _tail;
715
+ }
716
+
717
+ // Try to write the string as ASCII, return false if there's a non-ascii char.
718
+ @pragma ('vm:prefer-inline' )
719
+ bool _tryWriteASCIIString (String value) {
720
+ _prepare (4 , 1 , additionalBytes: value.length + 1 );
721
+ final length = value.length;
722
+ var offset = _buf.lengthInBytes - _tail + 4 ;
723
+ for (var i = 0 ; i < length; i++ ) {
724
+ // utf16 code unit, e.g. for '†' it's [0x20 0x20], which is 8224 decimal.
725
+ // ASCII characters go from 0x00 to 0x7F (which is 0 to 127 decimal).
726
+ final char = value.codeUnitAt (i);
727
+ if (char >= 128 ) {
728
+ return false ;
729
+ }
730
+ _buf.setUint8 (offset++ , char);
731
+ }
732
+ _buf.setUint8 (offset, 0 ); // trailing zero
733
+ _setUint32AtTail (_buf, _tail, value.length);
734
+ return true ;
735
+ }
736
+
737
+ @pragma ('vm:prefer-inline' )
738
+ void _writeUTFString (String value) {
739
+ final bytes = utf8.encode (value) as Uint8List ;
740
+ final length = bytes.length;
709
741
_prepare (4 , 1 , additionalBytes: length + 1 );
710
- final int result = _tail;
711
742
_setUint32AtTail (_buf, _tail, length);
712
- int offset = _buf.lengthInBytes - _tail + 4 ;
743
+ var offset = _buf.lengthInBytes - _tail + 4 ;
713
744
for (int i = 0 ; i < length; i++ ) {
714
745
_buf.setUint8 (offset++ , bytes[i]);
715
746
}
716
747
_buf.setUint8 (offset, 0 ); // trailing zero
717
- return result;
718
748
}
719
749
720
750
/// Throw an exception if there is not currently a vtable.
0 commit comments