mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 18:46:06 +00:00
[core] Improve JSON decoding performance
Avoid polymorphic character access by turning _ChunkedJsonParser into a mixin instead of the base class. TEST=ci Change-Id: Id2080724e07d16e96734a80629c8bd8906dc590b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/358445 Reviewed-by: Daco Harkes <dacoharkes@google.com> Commit-Queue: Slava Egorov <vegorov@google.com>
This commit is contained in:
parent
867610409a
commit
df80cf9140
|
@ -59,9 +59,7 @@ class _JsonUtf8Decoder extends Converter<List<int>, Object?> {
|
|||
|
||||
Object? convert(List<int> input) {
|
||||
var parser = _JsonUtf8DecoderSink._createParser(_reviver, _allowMalformed);
|
||||
parser.chunk = input;
|
||||
parser.chunkEnd = input.length;
|
||||
parser.parse(0);
|
||||
parser.parseChunk(input, 0, input.length);
|
||||
parser.close();
|
||||
return parser.result;
|
||||
}
|
||||
|
@ -249,6 +247,11 @@ class _NumberBuffer {
|
|||
double parseDouble() => double.parse(getString());
|
||||
}
|
||||
|
||||
abstract class _JsonParserWithListener {
|
||||
final _JsonListener listener;
|
||||
_JsonParserWithListener(this.listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Chunked JSON parser.
|
||||
*
|
||||
|
@ -256,8 +259,13 @@ class _NumberBuffer {
|
|||
* and stores input state between chunks.
|
||||
*
|
||||
* Implementations include [String] and UTF-8 parsers.
|
||||
*
|
||||
* Note: this is a mixin instead of the base class to allow compilers
|
||||
* to specialize applications otherwise accessing chunk characters becomes
|
||||
* polymorphic.
|
||||
*
|
||||
*/
|
||||
abstract class _ChunkedJsonParser<T> {
|
||||
mixin _ChunkedJsonParser<T> on _JsonParserWithListener {
|
||||
// A simple non-recursive state-based parser for JSON.
|
||||
//
|
||||
// Literal values accepted in states ARRAY_EMPTY, ARRAY_COMMA, OBJECT_COLON
|
||||
|
@ -388,8 +396,6 @@ abstract class _ChunkedJsonParser<T> {
|
|||
// Mask used to mask off two lower bits.
|
||||
static const int TWO_BIT_MASK = 3;
|
||||
|
||||
final _JsonListener listener;
|
||||
|
||||
// The current parsing state.
|
||||
int state = STATE_INITIAL;
|
||||
List<int> states = <int>[];
|
||||
|
@ -440,8 +446,6 @@ abstract class _ChunkedJsonParser<T> {
|
|||
*/
|
||||
dynamic buffer = null;
|
||||
|
||||
_ChunkedJsonParser(this.listener);
|
||||
|
||||
/**
|
||||
* Push the current parse [state] on a stack.
|
||||
*
|
||||
|
@ -1380,7 +1384,8 @@ abstract class _ChunkedJsonParser<T> {
|
|||
/**
|
||||
* Chunked JSON parser that parses [String] chunks.
|
||||
*/
|
||||
class _JsonStringParser extends _ChunkedJsonParser<String> {
|
||||
class _JsonStringParser extends _JsonParserWithListener
|
||||
with _ChunkedJsonParser<String> {
|
||||
String chunk = '';
|
||||
int chunkEnd = 0;
|
||||
|
||||
|
@ -1477,11 +1482,12 @@ class _JsonStringDecoderSink extends StringConversionSinkBase {
|
|||
/**
|
||||
* Chunked JSON parser that parses UTF-8 chunks.
|
||||
*/
|
||||
class _JsonUtf8Parser extends _ChunkedJsonParser<List<int>> {
|
||||
class _JsonUtf8Parser extends _JsonParserWithListener
|
||||
with _ChunkedJsonParser<Uint8List> {
|
||||
static final Uint8List emptyChunk = Uint8List(0);
|
||||
|
||||
final _Utf8Decoder decoder;
|
||||
List<int> chunk = emptyChunk;
|
||||
Uint8List chunk = emptyChunk;
|
||||
int chunkEnd = 0;
|
||||
|
||||
_JsonUtf8Parser(_JsonListener listener, bool allowMalformed)
|
||||
|
@ -1492,6 +1498,21 @@ class _JsonUtf8Parser extends _ChunkedJsonParser<List<int>> {
|
|||
_ChunkedJsonParser.PARTIAL_KEYWORD | _ChunkedJsonParser.KWD_BOM;
|
||||
}
|
||||
|
||||
void parseChunk(List<int> value, int start, int end) {
|
||||
if (value is Uint8List) {
|
||||
chunk = value;
|
||||
} else {
|
||||
final bytes = Uint8List(end - start);
|
||||
bytes.setRange(0, bytes.length, value, start);
|
||||
end = bytes.length;
|
||||
start = 0;
|
||||
chunk = bytes;
|
||||
}
|
||||
chunkEnd = end;
|
||||
parse(start);
|
||||
}
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
int getChar(int position) => chunk[position];
|
||||
|
||||
String getString(int start, int end, int bits) {
|
||||
|
@ -1569,9 +1590,7 @@ class _JsonUtf8DecoderSink extends ByteConversionSink {
|
|||
}
|
||||
|
||||
void _addChunk(List<int> chunk, int start, int end) {
|
||||
_parser.chunk = chunk;
|
||||
_parser.chunkEnd = end;
|
||||
_parser.parse(start);
|
||||
_parser.parseChunk(chunk, start, end);
|
||||
}
|
||||
|
||||
void close() {
|
||||
|
|
Loading…
Reference in a new issue