Browse Source

Test cases for string charlen improvement

- Fix string intern test case ("intern match"), which didn't keep a
  reference to the string so that the string was actually not already
  in the string table.

- Add character length computation performance test cases for both
  pure ASCII and non-ASCII strings.

- Add character length computation correctness test case, which exercises
  different string lengths and random string bytes.
pull/422/head
Sami Vaarala 9 years ago
parent
commit
36b8c7b4e7
  1. 71
      tests/ecmascript/test-dev-string-charlen-correctness.js
  2. 27
      tests/perf/test-string-charlen-ascii.js
  3. 27
      tests/perf/test-string-charlen-nonascii.js
  4. 2
      tests/perf/test-string-intern-match.js

71
tests/ecmascript/test-dev-string-charlen-correctness.js

@ -0,0 +1,71 @@
/*
* Ensure string character length calculation is correct even for invalid
* UTF-8 and various string lengths.
*
* The character length calculation is important for performance and the
* algorithm has optimizations which deal with e.g. different string lengths
* using separate code paths.
*/
/*---
{
"custom": true
}
---*/
/*===
done
===*/
function testOne(blen) {
var buf, str;
var i;
var clen;
buf = new Duktape.Buffer(blen);
for (i = 0; i < blen; i++) {
buf[i] = Math.random() * 256;
}
// Expected character length computed using Ecmascript:
// all bytes outside of [0x80,0xbf] (UTF-8 continuation
// bytes) contribute +1 to character length.
clen = 0;
for (i = 0; i < blen; i++) {
if (buf[i] < 0x80 || buf[i] >= 0xc0) {
clen++;
}
}
str = String(buf);
if (str.length != clen) {
throw new Error('mismatch: ' + str.length + ' vs ' + clen);
}
}
function test() {
var i, j;
var blen;
// Strings up to 256 bytes, a few times each
for (i = 0; i <= 256; i++) {
for (j = 0; j < 100; j++) {
testOne(i);
}
}
// Random strings up to 64kB, favor shorter strings
// Math.exp(0) - 1 = 0
// Math.exp(11.1) - 1 ~= 66170
for (i = 0; i < 1000; i++) {
blen = Math.max(Math.min(Math.floor(Math.exp(Math.random() * 11.1) - 1), 65536), 0);
testOne(blen);
}
}
try {
test();
print('done');
} catch (e) {
print(e.stack);
}

27
tests/perf/test-string-charlen-ascii.js

@ -0,0 +1,27 @@
/*
* Important fast path: character length for pure ASCII strings.
*/
if (typeof print !== 'function') { print = console.log; }
function test() {
var str;
var i, n;
str = 'aAbBcCdDeEfFgGhH';
while (str.length < 65536) {
str = str + str;
}
print(str.length);
for (i = 0; i < 1e5; i++) {
void (str + 'x').length;
}
}
try {
test();
} catch (e) {
print(e.stack || e);
throw e;
}

27
tests/perf/test-string-charlen-nonascii.js

@ -0,0 +1,27 @@
/*
* Character length for non-ASCII strings.
*/
if (typeof print !== 'function') { print = console.log; }
function test() {
var str;
var i, n;
str = '\u1234\u2345\u3456\u4567\u5678\u6789\u789a\u89ab\u9abc\uabcd\ubcde\ucdef\udef0\uef01\uf012\u0123';
while (str.length < 16384) {
str = str + str;
}
print(str.length);
for (i = 0; i < 1e5; i++) {
void (str + 'x').length;
}
}
try {
test();
} catch (e) {
print(e.stack || e);
throw e;
}

2
tests/perf/test-string-intern-match.js

@ -8,11 +8,13 @@ if (typeof print !== 'function') { print = console.log; }
function test() {
var buf = Duktape.Buffer(2048);
var ref;
var i;
for (i = 0; i < buf.length; i++) {
buf[i] = i;
}
ref = String(buf);
for (i = 0; i < 1e6; i++) {
void String(buf);

Loading…
Cancel
Save