@@ -703,18 +703,48 @@ class Builder {
703703 }
704704
705705 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;
709741 _prepare (4 , 1 , additionalBytes: length + 1 );
710- final int result = _tail;
711742 _setUint32AtTail (_buf, _tail, length);
712- int offset = _buf.lengthInBytes - _tail + 4 ;
743+ var offset = _buf.lengthInBytes - _tail + 4 ;
713744 for (int i = 0 ; i < length; i++ ) {
714745 _buf.setUint8 (offset++ , bytes[i]);
715746 }
716747 _buf.setUint8 (offset, 0 ); // trailing zero
717- return result;
718748 }
719749
720750 /// Throw an exception if there is not currently a vtable.
0 commit comments