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