Skip to content

Commit 5c0c426

Browse files
mkustermannCommit Queue
authored andcommitted
[dart2wasm] Improve double.toString() cache
=> We use wasm arrays to represent the cache used for stringifcation of doubles. => We store unboxed doubles as cache keys and thereby make the cache have a cache-hit if the double value is the same (before it was a cache-hit if the double box was identical). Change-Id: Id944f45188f29659b7704a7db5b321aafbe8c9ef Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/410001 Reviewed-by: Lasse Nielsen <[email protected]> Commit-Queue: Martin Kustermann <[email protected]>
1 parent b7178c2 commit 5c0c426

File tree

1 file changed

+29
-19
lines changed

1 file changed

+29
-19
lines changed

sdk/lib/_internal/wasm/lib/boxed_double.dart

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -318,29 +318,39 @@ final class BoxedDouble implements double {
318318
static const int CACHE_SIZE_LOG2 = 3;
319319
static const int CACHE_LENGTH = 1 << (CACHE_SIZE_LOG2 + 1);
320320
static const int CACHE_MASK = CACHE_LENGTH - 1;
321-
// Each key (double) followed by its toString result.
322-
static final List _cache = new List.filled(CACHE_LENGTH, null);
321+
// Each cached double value, represented as it's 64-bits.
322+
static final WasmArray<int> _cacheKeys = WasmArray<int>.filled(
323+
CACHE_LENGTH,
324+
doubleToIntBits(1.0),
325+
);
326+
// The toString() of the double value with same index in [_cacheKeys].
327+
static final WasmArray<String> _cacheValues = WasmArray<String>.filled(
328+
CACHE_LENGTH,
329+
'1.0',
330+
);
323331
static int _cacheEvictIndex = 0;
324332

325333
String toString() {
326-
// TODO(koda): Consider starting at most recently inserted.
327-
for (int i = 0; i < CACHE_LENGTH; i += 2) {
328-
// Need 'identical' to handle negative zero, etc.
329-
if (identical(_cache[i], this)) {
330-
return _cache[i + 1];
334+
final int bits = doubleToIntBits(value);
335+
336+
if (bits == doubleToIntBits(0.0)) return '0.0';
337+
if (bits == doubleToIntBits(-0.0)) return '-0.0';
338+
if (bits == doubleToIntBits(1.0)) return '1.0';
339+
if (bits == doubleToIntBits(-1.0)) return '-1.0';
340+
341+
for (int i = 0; i < CACHE_LENGTH; i++) {
342+
// Special cases such as -0.0/0.0 and NaN are never inserted into the
343+
// cache.
344+
if (bits == _cacheKeys[i]) {
345+
return _cacheValues[i];
331346
}
332347
}
333-
// TODO(koda): Consider optimizing all small integral values.
334348
if (isNaN) return "NaN";
335-
if (this == double.infinity) return "Infinity";
336-
if (this == -double.infinity) return "-Infinity";
337-
if (this == 0) {
338-
if (isNegative) {
339-
return "-0.0";
340-
} else {
341-
return "0.0";
342-
}
349+
if (isInfinite) {
350+
if (isNegative) return "-Infinity";
351+
return "Infinity";
343352
}
353+
344354
String result = jsStringToDartString(
345355
JSStringImpl(
346356
JS<WasmExternRef?>(
@@ -353,9 +363,9 @@ final class BoxedDouble implements double {
353363
result = '$result.0';
354364
}
355365
// Replace the least recently inserted entry.
356-
_cache[_cacheEvictIndex] = this;
357-
_cache[_cacheEvictIndex + 1] = result;
358-
_cacheEvictIndex = (_cacheEvictIndex + 2) & CACHE_MASK;
366+
_cacheKeys[_cacheEvictIndex] = bits;
367+
_cacheValues[_cacheEvictIndex] = result;
368+
_cacheEvictIndex = (_cacheEvictIndex + 1) & CACHE_MASK;
359369
return result;
360370
}
361371

0 commit comments

Comments
 (0)