[dart2wasm] Small optimization in JSON number parsing

Use `WasmArray<WasmI8>` for number buffer when decoding numbers.

This saves one allocation when growing the number buffer and on initial
allocation of the buffer, and eliminates one layer of indirection when
writing to the buffer.

Change-Id: Ic210bc13072f0dd34918361a1bee8c7b29ce61cd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371064
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This commit is contained in:
Ömer Sinan Ağacan 2024-06-12 10:50:27 +00:00 committed by Commit Queue
parent 5986f91820
commit 75f9312a50
2 changed files with 27 additions and 19 deletions

View file

@ -186,19 +186,19 @@ class _JsonListener {
* Buffer holding parts of a numeral.
*
* The buffer contains the characters of a JSON number.
* These are all ASCII, so an [Uint8List] is used as backing store.
* These are all ASCII, so an `array i8` is used as backing store.
*
* This buffer is used when a JSON number is split between separate chunks.
*/
class _NumberBuffer {
static const int minCapacity = 16;
static const int defaultOverhead = 5;
Uint8List list;
WasmArray<WasmI8> array;
int length = 0;
_NumberBuffer(int initialCapacity)
: list = new Uint8List(_initialCapacity(initialCapacity));
: array = WasmArray<WasmI8>(_initialCapacity(initialCapacity));
int get capacity => list.length;
int get capacity => array.length;
// Pick an initial capacity greater than the first part's size.
// The typical use case has two parts, this is the attempt at
@ -217,15 +217,15 @@ class _NumberBuffer {
// Grows to the exact size asked for.
void ensureCapacity(int newCapacity) {
Uint8List list = this.list;
if (newCapacity <= list.length) return;
Uint8List newList = new Uint8List(newCapacity);
newList.setRange(0, list.length, list, 0);
this.list = newList;
WasmArray<WasmI8> array = this.array;
if (newCapacity <= array.length) return;
WasmArray<WasmI8> newArray = WasmArray<WasmI8>(newCapacity);
newArray.copy(0, array, 0, array.length);
this.array = newArray;
}
String getString() {
String result = new String.fromCharCodes(list, 0, length);
String result = createOneByteStringFromCharactersArray(array, 0, length);
return result;
}
@ -536,7 +536,8 @@ mixin _ChunkedJsonParser<T> on _JsonParserWithListener {
*
* Used for number buffer (always copies ASCII, so encoding is not important).
*/
void copyCharsToList(int start, int end, List<int> target, int offset);
void copyCharsToList(
int start, int end, WasmArray<WasmI8> target, int offset);
/**
* Build a string using input code units.
@ -1245,7 +1246,7 @@ mixin _ChunkedJsonParser<T> on _JsonParserWithListener {
int end = chunkEnd;
int length = end - start;
var buffer = new _NumberBuffer(length);
copyCharsToList(start, end, buffer.list, 0);
copyCharsToList(start, end, buffer.array, 0);
buffer.length = length;
this.buffer = buffer;
this.partialState = PARTIAL_NUMERAL | state;
@ -1258,7 +1259,7 @@ mixin _ChunkedJsonParser<T> on _JsonParserWithListener {
int newCount = count + length;
int newCapacity = newCount + overhead;
buffer.ensureCapacity(newCapacity);
copyCharsToList(start, end, buffer.list, count);
copyCharsToList(start, end, buffer.array, count);
buffer.length = newCount;
}
@ -1495,10 +1496,11 @@ class _JsonStringParser extends _JsonParserWithListener
return buffer.toString();
}
void copyCharsToList(int start, int end, List<int> target, int offset) {
void copyCharsToList(
int start, int end, WasmArray<WasmI8> target, int offset) {
int length = end - start;
for (int i = 0; i < length; i++) {
target[offset + i] = chunk.codeUnitAt(start + i);
target.write(offset + i, chunk.codeUnitAt(start + i));
}
}
@ -1630,9 +1632,10 @@ class _JsonUtf8Parser extends _JsonParserWithListener
return buffer.toString();
}
void copyCharsToList(int start, int end, List<int> target, int offset) {
void copyCharsToList(
int start, int end, WasmArray<WasmI8> target, int offset) {
int length = end - start;
target.setRange(offset, offset + length, chunk, start);
target.copy(offset, chunk.data, start, length);
}
double parseDouble(int start, int end) {

View file

@ -55,10 +55,15 @@ void copyRangeFromUint8ListToOneByteString(
@pragma("wasm:prefer-inline")
OneByteString createOneByteStringFromCharacters(
U8List bytes, int start, int end) {
U8List bytes, int start, int end) =>
createOneByteStringFromCharactersArray(bytes.data, start, end);
@pragma("wasm:prefer-inline")
OneByteString createOneByteStringFromCharactersArray(
WasmArray<WasmI8> bytes, int start, int end) {
final len = end - start;
final s = OneByteString.withLength(len);
s._array.copy(0, bytes.data, start, len);
s._array.copy(0, bytes, start, len);
return s;
}