runsunspider.js revision 818:26a5fdb90de2
1/* 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24/** 25 * runsunspider : runs the sunspider tests and checks for compliance 26 * 27 * @subtest 28 */ 29 30/** 31 * This is not a test, but a test "framework" for running sunspider tests. 32 */ 33 34function assertEq(a, b) { 35 if (a !== b) { 36 throw "ASSERTION FAILED: " + a + " should be " + b; 37 } 38} 39 40function pprint(x) { 41 if (verbose_run) { 42 print(x); 43 } 44} 45 46var runs = 0; 47var total_time = 0; 48 49function runbench(name) { 50 var filename = name.split("/").pop(); 51 pprint("Running (warmup/sanity) " + filename); 52 53 var start = new Date; 54 load(name); 55 var stop = new Date - start; 56 total_time += stop; 57 58 pprint(filename + " done in " + stop + " ms"); 59 runs++; 60} 61 62var m_w; 63var m_z; 64var MAXINT; 65 66//produce deterministic random numbers for test suite 67function pseudorandom() { 68 m_z = 36969 * (m_z & 65535) + (m_z >> 16); 69 m_w = 18000 * (m_w & 65535) + (m_w >> 16); 70 return (Math.abs((m_z << 16) + m_w) & MAXINT) / MAXINT; 71} 72 73function initrandom() { 74 m_w = 4711; 75 m_z = 17; 76 MAXINT = 0x7fffffff; 77 Math.random = pseudorandom; 78} 79 80var rtimes = 0; 81var dir = (typeof(__DIR__) == 'undefined') ? "test/script/basic/" : __DIR__; 82var single; 83var verbose_run = false; 84 85var args = []; 86if (typeof $ARGS !== 'undefined') { 87 args = $ARGS; 88} else if (typeof arguments !== 'undefined' && arguments.length != 0) { 89 args = arguments; 90} 91 92for (var i = 0; i < args.length; i++) { 93 if (args[i] === '--verbose') { 94 verbose_run = true; 95 } else if (args[i] === '--times') { 96 i++; 97 rtimes = +args[i]; 98 } else if (args[i] === '--single') { 99 i++; 100 single = args[i]; 101 } 102} 103 104function runsuite(tests) { 105 var changed = false; 106 var res = []; 107 var oldRandom = Math.random; 108 109 try { 110 for (var n = 0; n < tests.length; n++) { 111 path = dir + '../external/sunspider/tests/sunspider-1.0.2/' + tests[n].name 112 113 initrandom(); 114 115 var dd = new Date; 116 117 runbench(path); 118 if (typeof tests[n].actual !== 'undefined') { 119 assertEq(tests[n].actual(), tests[n].expected()); 120 } 121 122 if (typeof tests[n].rerun !== 'undefined' && tests[n].times > 0) { 123 pprint("rerunning " + tests[n].name + " " + tests[n].times + " times..."); 124 var times = 0; 125 var to = tests[n].times; 126 127 var elemsPerPercent = to / 100; 128 var po = 0|(to / 10); 129 130 times = 0; 131 for (; times < to; times++) { 132 initrandom(); 133 tests[n].rerun(); 134 if ((times % (po|0)) == 0) { 135 pprint(times/to * 100 + "%"); 136 } 137 } 138 } 139 140 var t = new Date - dd; 141 pprint("time: " + t + " ms"); 142 if (typeof tests[n].actual !== 'undefined') { 143 assertEq(tests[n].actual(), tests[n].expected()); 144 } 145 res.push(t); 146 147 pprint(""); 148 149 changed = true; 150 } 151 } catch (e) { 152 print("FAIL!"); 153 throw e; 154 // no scripting or something, silently fail 155 } finally { 156 Math.random = oldRandom; 157 } 158 159 for (var n = 0; n < tests.length; n++) { 160 161 var time = "" + res[n]; 162 while (time.length < 4) { 163 time = " " + time; 164 } 165 time += " ms"; 166 if (res[n] == -1) { 167 time = "<couldn't be rerun>"; 168 } 169 var str = tests[n].name; 170 for (var spaces = str.length; spaces < 32; spaces++) { 171 str += " "; 172 } 173 str += " "; 174 str += time; 175 176 if (tests[n].times > 0) { 177 str += " ["; 178 str += tests[n].times + " reruns]"; 179 } 180 pprint(str); 181 } 182 183 return changed; 184} 185 186function hash(str) { 187 var s = "" + str; 188 var h = 0; 189 var off = 0; 190 for (var i = 0; i < s.length; i++) { 191 h = 31 * h + s.charCodeAt(off++); 192 h &= 0x7fffffff; 193 } 194 return h ^ s.length; 195} 196 197var tests = [ 198 199 { name: 'regexp-dna.js', 200 actual: function() { 201 return dnaOutputString + dnaInput; 202 }, 203 expected: function() { 204 return expectedDNAOutputString + expectedDNAInput; 205 }, 206 }, 207 208 { name: 'string-base64.js', 209 actual: function() { 210 return hash(str); 211 }, 212 expected: function() { 213 return 1544571068; 214 }, 215 times: rtimes, 216 rerun: function() { 217 toBinaryTable = [ 218 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, 219 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, 220 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, 221 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, 222 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, 223 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, 224 -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, 225 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 226 ]; 227 var str = ""; 228 for (var i = 0; i < 8192; i++) 229 str += String.fromCharCode((25 * Math.random()) + 97); 230 231 for (var i = 8192; i <= 16384; i *= 2) { 232 var base64; 233 base64 = toBase64(str); 234 var encoded = base64ToString(base64); 235 236 str += str; 237 } 238 toBinaryTable = null; 239 } 240 }, 241 { name: 'date-format-xparb.js', 242 actual: function() { 243 return shortFormat + longFormat; 244 }, 245 expected: function() { 246 return "2017-09-05Tuesday, September 05, 2017 8:43:48 AM"; 247 }, 248 times: rtimes, 249 rerun: function() { 250 date = new Date("1/1/2007 1:11:11"); 251 for (i = 0; i < 4000; ++i) { 252 var shortFormat = date.dateFormat("Y-m-d"); 253 var longFormat = date.dateFormat("l, F d, Y g:i:s A"); 254 date.setTime(date.getTime() + 84266956); 255 } 256 } 257 258 }, 259 { name: 'string-validate-input.js', 260 actual: function() { 261 return hash(endResult); 262 }, 263 expected: function() { 264 return 726038055; 265 }, 266 times: rtimes, 267 rerun: function() { 268 doTest(); 269 }, 270 }, 271 { name: '3d-morph.js', 272 actual: function() { 273 var acceptableDelta = 4e-15; 274 return (testOutput - 6.394884621840902e-14) < acceptableDelta; 275 }, 276 expected: function() { 277 return true; 278 }, 279 times: rtimes, 280 rerun: function() { 281 a = Array() 282 for (var i=0; i < nx*nz*3; ++i) 283 a[i] = 0 284 for (var i = 0; i < loops; ++i) { 285 morph(a, i/loops) 286 } 287 testOutput = 0; 288 for (var i = 0; i < nx; i++) 289 testOutput += a[3*(i*nx+i)+1]; 290 a = null; 291 292 } 293 }, 294 { name: 'crypto-aes.js', 295 actual: function() { 296 return plainText; 297 }, 298 expected: function() { 299 return decryptedText; 300 }, 301 times: rtimes, 302 rerun: function() { 303 cipherText = AESEncryptCtr(plainText, password, 256); 304 decryptedText = AESDecryptCtr(cipherText, password, 256); 305 306 } 307 }, 308 { name: 'crypto-md5.js', 309 actual: function() { 310 return md5Output; 311 }, 312 expected: function() { 313 return "a831e91e0f70eddcb70dc61c6f82f6cd"; 314 }, 315 times: rtimes, 316 rerun: function() { 317 md5Output = hex_md5(plainText); 318 } 319 }, 320 321 { name: 'crypto-sha1.js', 322 actual: function() { 323 return sha1Output; 324 }, 325 expected: function() { 326 return "2524d264def74cce2498bf112bedf00e6c0b796d"; 327 }, 328 times: rtimes, 329 rerun: function() { 330 sha1Output = hex_sha1(plainText); 331 } 332 }, 333 334 { name: 'bitops-bitwise-and.js', 335 actual: function() { 336 return result; 337 }, 338 expected: function() { 339 return 0; 340 }, 341 times: rtimes, 342 rerun: function() { 343 bitwiseAndValue = 4294967296; 344 for (var i = 0; i < 600000; i++) { 345 bitwiseAndValue = bitwiseAndValue & i; 346 } 347 result = bitwiseAndValue; 348 } 349 }, 350 351 { name: 'bitops-bits-in-byte.js', 352 actual: function() { 353 return result; 354 }, 355 expected: function() { 356 return 358400; 357 }, 358 times: rtimes, 359 rerun: function() { 360 result = TimeFunc(bitsinbyte); 361 } 362 }, 363 364 { name: 'bitops-nsieve-bits.js', 365 actual: function() { 366 var ret = 0; 367 for (var i = 0; i < result.length; ++i) { 368 ret += result[i]; 369 } 370 ret += result.length; 371 return ret; 372 }, 373 expected: function() { 374 return -1286749539853; 375 }, 376 times: rtimes, 377 rerun: function() { 378 result = sieve(); 379 } 380 }, 381 382 { name: 'bitops-3bit-bits-in-byte.js', 383 actual: function() { 384 return sum; 385 }, 386 expected: function() { 387 return 512000; 388 }, 389 times: rtimes, 390 rerun: function() { 391 sum = TimeFunc(fast3bitlookup); 392 } 393 }, 394 395 { name: 'access-nbody.js', 396 actual: function() { 397 return ret; 398 }, 399 expected: function() { 400 return -1.3524862408537381; 401 }, 402 times: rtimes, 403 rerun: function() { 404 var ret = 0; 405 for (var n = 3; n <= 24; n *= 2) { 406 (function(){ 407 var bodies = new NBodySystem( Array( 408 Sun(),Jupiter(),Saturn(),Uranus(),Neptune() 409 )); 410 var max = n * 100; 411 412 ret += bodies.energy(); 413 for (var i=0; i<max; i++){ 414 bodies.advance(0.01); 415 } 416 ret += bodies.energy(); 417 })(); 418 } 419 } 420 }, 421 422 { name: 'access-binary-trees.js', 423 actual: function() { 424 return ret; 425 }, 426 expected: function() { 427 return -4; 428 }, 429 times: rtimes, 430 rerun: function() { 431 ret = 0; 432 433 for (var n = 4; n <= 7; n += 1) { 434 var minDepth = 4; 435 var maxDepth = Math.max(minDepth + 2, n); 436 var stretchDepth = maxDepth + 1; 437 438 var check = bottomUpTree(0,stretchDepth).itemCheck(); 439 440 var longLivedTree = bottomUpTree(0,maxDepth); 441 for (var depth=minDepth; depth<=maxDepth; depth+=2){ 442 var iterations = 1 << (maxDepth - depth + minDepth); 443 444 check = 0; 445 for (var i=1; i<=iterations; i++){ 446 check += bottomUpTree(i,depth).itemCheck(); 447 check += bottomUpTree(-i,depth).itemCheck(); 448 } 449 } 450 451 ret += longLivedTree.itemCheck(); 452 } 453 } 454 }, 455 456 { name: 'access-fannkuch.js', 457 actual: function() { 458 return ret; 459 }, 460 expected: function() { 461 return 22; 462 }, 463 times: rtimes, 464 rerun: function() { 465 n = 8; 466 ret = fannkuch(n); 467 } 468 }, 469 470 { name: 'math-spectral-norm.js', 471 actual: function() { 472 var ret = ''; 473 for (var i = 6; i <= 48; i *= 2) { 474 ret += spectralnorm(i) + ','; 475 } 476 return ret; 477 }, 478 expected: function() { 479 return "1.2657786149754053,1.2727355112619148,1.273989979775574,1.274190125290389,"; 480 }, 481 times: rtimes, 482 rerun: function() { 483 total = 0; 484 for (var i = 6; i <= 48; i *= 2) { 485 total += spectralnorm(i); 486 } 487 } 488 }, 489 490 { name: '3d-raytrace.js', 491 actual: function() { 492 return hash(testOutput); 493 }, 494 expected: function() { 495 return 230692593; 496 }, 497 times: rtimes, 498 rerun: function() { 499 testOutput = arrayToCanvasCommands(raytraceScene()); 500 } 501 }, 502 503 { name: 'math-cordic.js', 504 actual: function() { 505 return total; 506 }, 507 expected: function() { 508 return 10362.570468755888; 509 }, 510 times: rtimes, 511 rerun: function() { 512 total = 0; 513 cordic(25000); 514 } 515 }, 516 517 { name: 'controlflow-recursive.js', 518 actual: function() { 519 var ret = 0; 520 for (var i = 3; i <= 5; i++) { 521 ret += ack(3,i); 522 ret += fib(17.0+i); 523 ret += tak(3*i+3,2*i+2,i+1); 524 } 525 return ret; 526 }, 527 expected: function() { 528 return 57775; 529 }, 530 times: rtimes, 531 rerun: function() { 532 result = 0; 533 for (var i = 3; i <= 5; i++) { 534 result += ack(3,i); 535 result += fib(17.0+i); 536 result += tak(3*i+3,2*i+2,i+1); 537 } 538 } 539 }, 540 541 { name: 'date-format-tofte.js', 542 actual: function() { 543 return shortFormat + longFormat; 544 }, 545 expected: function() { 546 return "2008-05-01Thursday, May 01, 2008 6:31:22 PM"; 547 }, 548 times: rtimes, 549 rerun: function() { 550 date = new Date("1/1/2007 1:11:11"); 551 for (i = 0; i < 500; ++i) { 552 var shortFormat = date.formatDate("Y-m-d"); 553 var longFormat = date.formatDate("l, F d, Y g:i:s A"); 554 date.setTime(date.getTime() + 84266956); 555 } 556 } 557 }, 558 559 { name: 'string-tagcloud.js', 560 actual: function() { 561 // The result string embeds floating-point numbers, which can vary a bit on different platforms, 562 // so we truncate them a bit before comparing. 563 var tagcloud_norm = tagcloud.replace(/([0-9.]+)px/g, function(str, p1) { return p1.substr(0, 10) + 'px' }) 564 return tagcloud_norm.length; 565 }, 566 expected: function() { 567 return 295906; 568 }, 569 times: rtimes, 570 rerun: function() { 571 tagInfo = tagInfoJSON.parseJSON(function(a, b) { if (a == "popularity") { return Math.log(b) / log2; } else {return b; } }); 572 tagcloud = makeTagCloud(tagInfo); 573 } 574 }, 575 576 { name: 'math-partial-sums.js', 577 actual: function() { 578 return total; 579 }, 580 expected: function() { 581 return 60.08994194659945; 582 }, 583 times: rtimes, 584 rerun: function() { 585 total = 0; 586 for (var i = 1024; i <= 16384; i *= 2) { 587 total += partial(i); 588 } 589 } 590 }, 591 592 { name: 'access-nsieve.js', 593 actual: function() { 594 return result; 595 }, 596 expected: function() { 597 return 14302; 598 }, 599 times: rtimes, 600 rerun: function() { 601 result = sieve(); 602 } 603 }, 604 605 { name: '3d-cube.js', 606 times: rtimes, 607 rerun: function() { 608 Q = new Array(); 609 MTrans = new Array(); // transformation matrix 610 MQube = new Array(); // position information of qube 611 I = new Array(); // entity matrix 612 Origin = new Object(); 613 Testing = new Object(); 614 for ( var i = 20; i <= 160; i *= 2 ) { 615 Init(i); 616 } 617 } 618 }, 619 620 //TODO no easy way to sanity check result 621 { name: 'string-fasta.js', 622 times: rtimes, 623 rerun: function() { 624 ret = 0; 625 count = 7; 626 fastaRepeat(2*count*100000, ALU); 627 fastaRandom(3*count*1000, IUB); 628 fastaRandom(5*count*1000, HomoSap); 629 } 630 }, 631 632 //TODO no easy way to sanity check result 633 { name: 'string-unpack-code.js', 634 actual: function() { 635 return decompressedMochiKit.length == 106415 && 636 decompressedMochiKit[2000] == '5' && 637 decompressedMochiKit[12000] == '_' && 638 decompressedMochiKit[82556] == '>'; 639 }, 640 expected: function() { 641 return true; 642 }, 643 }, 644 645]; 646 647tests.sort(function(a,b) { return a.name.localeCompare(b.name); }); 648if (typeof single !== 'undefined') { 649 for (i in tests) { 650 if (tests[i].name === single) { 651 singleTest = tests[i]; 652 tests = [singleTest]; 653 break; 654 } 655 } 656 if (tests.length != 1) { 657 throw "unknown single test '" + single + "'"; 658 } 659} 660 661 662// handle the case this script may be run by a JS engine that doesn't 663// support __DIR__ global variable. 664 665runsuite(tests); 666 667pprint('\n' + runs + "/" + tests.length + " tests were successfully run in " + total_time + " ms "); 668 669print("Sunspider finished!"); 670