From ede8e14355dfabbf41d687cbeae2240f8231f581 Mon Sep 17 00:00:00 2001 From: "fpizlo@apple.com" Date: Thu, 5 Sep 2013 02:53:16 +0000 Subject: [PATCH] Introduce a version of SunSpider that runs for a really long time (about 1 sec on my machine) Rubber stamped by Mark Hahnenberg. This isn't meant for serious VM-to-VM performance comparisons, but it is useful to see how these benchmarks behave when they're completely warmed up. * LongSpider: Added. * LongSpider/3d-cube.js: Added. (DrawLine): (CalcCross): (CalcNormal): (CreateP): (MMulti): (VMulti): (VMulti2): (MAdd): (Translate): (RotateX): (RotateY): (RotateZ): (DrawQube): (Loop): (Init): * LongSpider/3d-morph.js: Added. (loops.3500.nx.120.nz.120.morph): * LongSpider/3d-raytrace.js: Added. (createVector): (sqrLengthVector): (lengthVector): (addVector): (subVector): (scaleVector): (normaliseVector): (add): (sub): (scalev): (dot): (scale): (cross): (normalise): (transformMatrix): (invertMatrix): (Triangle): (Triangle.prototype.intersect): (Scene): (Scene.prototype.intersect): (Scene.prototype.blocked): (Camera): (Camera.prototype.generateRayPair): (renderRows): (Camera.prototype.render): (raytraceScene.floorShader): (raytraceScene): (arrayToCanvasCommands): * LongSpider/access-binary-trees.js: Added. (TreeNode): (TreeNode.prototype.itemCheck): (bottomUpTree): * LongSpider/access-fannkuch.js: Added. (fannkuch): * LongSpider/access-nbody.js: Added. (Body): (Body.prototype.offsetMomentum): (Jupiter): (Saturn): (Uranus): (Neptune): (Sun): (NBodySystem): (NBodySystem.prototype.advance): (NBodySystem.prototype.energy): * LongSpider/access-nsieve.js: Added. (pad): (nsieve): (sieve): * LongSpider/bitops-3bit-bits-in-byte.js: Added. (fast3bitlookup): (TimeFunc): * LongSpider/bitops-bits-in-byte.js: Added. (bitsinbyte): (TimeFunc): * LongSpider/bitops-nsieve-bits.js: Added. (pad): (primes): (sieve): * LongSpider/controlflow-recursive.js: Added. (ack): (fib): (tak): * LongSpider/crypto-aes.js: Added. (Cipher): (SubBytes): (ShiftRows): (MixColumns): (AddRoundKey): (KeyExpansion): (SubWord): (RotWord): (AESEncryptCtr): (AESDecryptCtr): (escCtrlChars): * LongSpider/crypto-md5.js: Added. (hex_md5): (b64_md5): (str_md5): (hex_hmac_md5): (b64_hmac_md5): (str_hmac_md5): (md5_vm_test): (core_md5): (md5_cmn): (md5_ff): (md5_gg): (md5_hh): (md5_ii): (core_hmac_md5): (safe_add): (bit_rol): (str2binl): (binl2str): (binl2hex): (binl2b64): * LongSpider/crypto-sha1.js: Added. (hex_sha1): (b64_sha1): (str_sha1): (hex_hmac_sha1): (b64_hmac_sha1): (str_hmac_sha1): (sha1_vm_test): (core_sha1): (sha1_ft): (sha1_kt): (core_hmac_sha1): (safe_add): (rol): (str2binb): (binb2str): (binb2hex): (binb2b64): * LongSpider/date-format-tofte.js: Added. (arrayExists): (.a): (.A): (.B): (.d): (.D): (.F): (.g): (.G): (.h): (.H): (.i): (.j): (.l): (.L): (.m): (.M): (.n): (.O): (.r): (.S): (.s): (.t): (.U): (.W): (.w): (.Y): (.y): (.z): (Date.prototype.formatDate): * LongSpider/date-format-xparb.js: Added. (Date.prototype.dateFormat): (Date.createNewFormat): (Date.getFormatCode): (Date.parseDate): (Date.createParser): (Date.formatCodeToRegex): (Date.prototype.getTimezone): (Date.prototype.getGMTOffset): (Date.prototype.getDayOfYear): (Date.prototype.getWeekOfYear): (Date.prototype.isLeapYear): (Date.prototype.getFirstDayOfMonth): (Date.prototype.getLastDayOfMonth): (Date.prototype.getDaysInMonth): (Date.prototype.getSuffix): (String.escape): * LongSpider/math-cordic.js: Added. (FIXED): (FLOAT): (DEG2RAD): (cordicsincos): (cordic): * LongSpider/math-partial-sums.js: Added. (partial): * LongSpider/math-spectral-norm.js: Added. (A): (Au): (Atu): (AtAu): (spectralnorm): * LongSpider/string-base64.js: Added. (toBase64): (base64ToString): * LongSpider/string-fasta.js: Added. (rand): (makeCumulative): (fastaRepeat): (fastaRandom): * LongSpider/string-tagcloud.js: Added. (.Array.prototype.toJSONString): (.Boolean.prototype.toJSONString): (.Date.prototype.toJSONString): (.Number.prototype.toJSONString): (.Object.prototype.toJSONString): (.): git-svn-id: https://svn.webkit.org/repository/webkit/trunk@155088 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- PerformanceTests/ChangeLog | 221 ++++++++++ PerformanceTests/LongSpider/3d-cube.js | 365 +++++++++++++++++ PerformanceTests/LongSpider/3d-morph.js | 63 +++ PerformanceTests/LongSpider/3d-raytrace.js | 450 +++++++++++++++++++++ PerformanceTests/LongSpider/access-binary-trees.js | 54 +++ PerformanceTests/LongSpider/access-fannkuch.js | 70 ++++ PerformanceTests/LongSpider/access-nbody.js | 174 ++++++++ PerformanceTests/LongSpider/access-nsieve.js | 46 +++ .../LongSpider/bitops-3bit-bits-in-byte.js | 40 ++ PerformanceTests/LongSpider/bitops-bits-in-byte.js | 30 ++ PerformanceTests/LongSpider/bitops-nsieve-bits.js | 42 ++ .../LongSpider/controlflow-recursive.js | 32 ++ PerformanceTests/LongSpider/crypto-aes.js | 429 ++++++++++++++++++++ PerformanceTests/LongSpider/crypto-md5.js | 295 ++++++++++++++ PerformanceTests/LongSpider/crypto-sha1.js | 231 +++++++++++ PerformanceTests/LongSpider/date-format-tofte.js | 301 ++++++++++++++ PerformanceTests/LongSpider/date-format-xparb.js | 420 +++++++++++++++++++ PerformanceTests/LongSpider/math-cordic.js | 106 +++++ PerformanceTests/LongSpider/math-partial-sums.js | 45 +++ PerformanceTests/LongSpider/math-spectral-norm.js | 59 +++ PerformanceTests/LongSpider/string-base64.js | 137 +++++++ PerformanceTests/LongSpider/string-fasta.js | 90 +++++ PerformanceTests/LongSpider/string-tagcloud.js | 274 +++++++++++++ 23 files changed, 3974 insertions(+) create mode 100644 PerformanceTests/LongSpider/3d-cube.js create mode 100644 PerformanceTests/LongSpider/3d-morph.js create mode 100644 PerformanceTests/LongSpider/3d-raytrace.js create mode 100644 PerformanceTests/LongSpider/access-binary-trees.js create mode 100644 PerformanceTests/LongSpider/access-fannkuch.js create mode 100644 PerformanceTests/LongSpider/access-nbody.js create mode 100644 PerformanceTests/LongSpider/access-nsieve.js create mode 100644 PerformanceTests/LongSpider/bitops-3bit-bits-in-byte.js create mode 100644 PerformanceTests/LongSpider/bitops-bits-in-byte.js create mode 100644 PerformanceTests/LongSpider/bitops-nsieve-bits.js create mode 100644 PerformanceTests/LongSpider/controlflow-recursive.js create mode 100644 PerformanceTests/LongSpider/crypto-aes.js create mode 100644 PerformanceTests/LongSpider/crypto-md5.js create mode 100644 PerformanceTests/LongSpider/crypto-sha1.js create mode 100644 PerformanceTests/LongSpider/date-format-tofte.js create mode 100644 PerformanceTests/LongSpider/date-format-xparb.js create mode 100644 PerformanceTests/LongSpider/math-cordic.js create mode 100644 PerformanceTests/LongSpider/math-partial-sums.js create mode 100644 PerformanceTests/LongSpider/math-spectral-norm.js create mode 100644 PerformanceTests/LongSpider/string-base64.js create mode 100644 PerformanceTests/LongSpider/string-fasta.js create mode 100644 PerformanceTests/LongSpider/string-tagcloud.js diff --git a/PerformanceTests/ChangeLog b/PerformanceTests/ChangeLog index 726f172..7b98b45 100644 --- a/PerformanceTests/ChangeLog +++ b/PerformanceTests/ChangeLog @@ -1,3 +1,224 @@ +2013-09-04 Filip Pizlo + + Introduce a version of SunSpider that runs for a really long time (about 1 sec on my machine) + + Rubber stamped by Mark Hahnenberg. + + This isn't meant for serious VM-to-VM performance comparisons, but it is useful + to see how these benchmarks behave when they're completely warmed up. + + * LongSpider: Added. + * LongSpider/3d-cube.js: Added. + (DrawLine): + (CalcCross): + (CalcNormal): + (CreateP): + (MMulti): + (VMulti): + (VMulti2): + (MAdd): + (Translate): + (RotateX): + (RotateY): + (RotateZ): + (DrawQube): + (Loop): + (Init): + * LongSpider/3d-morph.js: Added. + (loops.3500.nx.120.nz.120.morph): + * LongSpider/3d-raytrace.js: Added. + (createVector): + (sqrLengthVector): + (lengthVector): + (addVector): + (subVector): + (scaleVector): + (normaliseVector): + (add): + (sub): + (scalev): + (dot): + (scale): + (cross): + (normalise): + (transformMatrix): + (invertMatrix): + (Triangle): + (Triangle.prototype.intersect): + (Scene): + (Scene.prototype.intersect): + (Scene.prototype.blocked): + (Camera): + (Camera.prototype.generateRayPair): + (renderRows): + (Camera.prototype.render): + (raytraceScene.floorShader): + (raytraceScene): + (arrayToCanvasCommands): + * LongSpider/access-binary-trees.js: Added. + (TreeNode): + (TreeNode.prototype.itemCheck): + (bottomUpTree): + * LongSpider/access-fannkuch.js: Added. + (fannkuch): + * LongSpider/access-nbody.js: Added. + (Body): + (Body.prototype.offsetMomentum): + (Jupiter): + (Saturn): + (Uranus): + (Neptune): + (Sun): + (NBodySystem): + (NBodySystem.prototype.advance): + (NBodySystem.prototype.energy): + * LongSpider/access-nsieve.js: Added. + (pad): + (nsieve): + (sieve): + * LongSpider/bitops-3bit-bits-in-byte.js: Added. + (fast3bitlookup): + (TimeFunc): + * LongSpider/bitops-bits-in-byte.js: Added. + (bitsinbyte): + (TimeFunc): + * LongSpider/bitops-nsieve-bits.js: Added. + (pad): + (primes): + (sieve): + * LongSpider/controlflow-recursive.js: Added. + (ack): + (fib): + (tak): + * LongSpider/crypto-aes.js: Added. + (Cipher): + (SubBytes): + (ShiftRows): + (MixColumns): + (AddRoundKey): + (KeyExpansion): + (SubWord): + (RotWord): + (AESEncryptCtr): + (AESDecryptCtr): + (escCtrlChars): + * LongSpider/crypto-md5.js: Added. + (hex_md5): + (b64_md5): + (str_md5): + (hex_hmac_md5): + (b64_hmac_md5): + (str_hmac_md5): + (md5_vm_test): + (core_md5): + (md5_cmn): + (md5_ff): + (md5_gg): + (md5_hh): + (md5_ii): + (core_hmac_md5): + (safe_add): + (bit_rol): + (str2binl): + (binl2str): + (binl2hex): + (binl2b64): + * LongSpider/crypto-sha1.js: Added. + (hex_sha1): + (b64_sha1): + (str_sha1): + (hex_hmac_sha1): + (b64_hmac_sha1): + (str_hmac_sha1): + (sha1_vm_test): + (core_sha1): + (sha1_ft): + (sha1_kt): + (core_hmac_sha1): + (safe_add): + (rol): + (str2binb): + (binb2str): + (binb2hex): + (binb2b64): + * LongSpider/date-format-tofte.js: Added. + (arrayExists): + (.a): + (.A): + (.B): + (.d): + (.D): + (.F): + (.g): + (.G): + (.h): + (.H): + (.i): + (.j): + (.l): + (.L): + (.m): + (.M): + (.n): + (.O): + (.r): + (.S): + (.s): + (.t): + (.U): + (.W): + (.w): + (.Y): + (.y): + (.z): + (Date.prototype.formatDate): + * LongSpider/date-format-xparb.js: Added. + (Date.prototype.dateFormat): + (Date.createNewFormat): + (Date.getFormatCode): + (Date.parseDate): + (Date.createParser): + (Date.formatCodeToRegex): + (Date.prototype.getTimezone): + (Date.prototype.getGMTOffset): + (Date.prototype.getDayOfYear): + (Date.prototype.getWeekOfYear): + (Date.prototype.isLeapYear): + (Date.prototype.getFirstDayOfMonth): + (Date.prototype.getLastDayOfMonth): + (Date.prototype.getDaysInMonth): + (Date.prototype.getSuffix): + (String.escape): + * LongSpider/math-cordic.js: Added. + (FIXED): + (FLOAT): + (DEG2RAD): + (cordicsincos): + (cordic): + * LongSpider/math-partial-sums.js: Added. + (partial): + * LongSpider/math-spectral-norm.js: Added. + (A): + (Au): + (Atu): + (AtAu): + (spectralnorm): + * LongSpider/string-base64.js: Added. + (toBase64): + (base64ToString): + * LongSpider/string-fasta.js: Added. + (rand): + (makeCumulative): + (fastaRepeat): + (fastaRandom): + * LongSpider/string-tagcloud.js: Added. + (.Array.prototype.toJSONString): + (.Boolean.prototype.toJSONString): + (.Date.prototype.toJSONString): + (.Number.prototype.toJSONString): + (.Object.prototype.toJSONString): + (.): + 2013-06-10 Radu Stavila [CSS Regions] Rename region-overflow to region-fragment diff --git a/PerformanceTests/LongSpider/3d-cube.js b/PerformanceTests/LongSpider/3d-cube.js new file mode 100644 index 0000000..600b3c0 --- /dev/null +++ b/PerformanceTests/LongSpider/3d-cube.js @@ -0,0 +1,365 @@ +// 3D Cube Rotation +// http://www.speich.net/computer/moztesting/3d.htm +// Created by Simon Speich + +var Q = new Array(); +var MTrans = new Array(); // transformation matrix +var MQube = new Array(); // position information of qube +var I = new Array(); // entity matrix +var Origin = new Object(); +var Testing = new Object(); +var LoopTimer; + +var validation = { + 20: 2889.0000000000045, + 40: 2889.0000000000055, + 80: 2889.000000000005, + 160: 2889.0000000000055, + 320: 2889.000000000006, + 640: 2889.000000000013, + 1280: 2888.9999999999923, + 2560: 2888.9999999999463, + 5120: 2889.0000000000405, + 10240: 2889.0000000002497, + 20480: 2889.0000000000405, + 40960: 2888.999999999462, + 81920: 2888.999999999193, + 163840: 2888.999999998356 +}; + +var DisplArea = new Object(); +DisplArea.Width = 300; +DisplArea.Height = 300; + +function DrawLine(From, To) { + var x1 = From.V[0]; + var x2 = To.V[0]; + var y1 = From.V[1]; + var y2 = To.V[1]; + var dx = Math.abs(x2 - x1); + var dy = Math.abs(y2 - y1); + var x = x1; + var y = y1; + var IncX1, IncY1; + var IncX2, IncY2; + var Den; + var Num; + var NumAdd; + var NumPix; + + if (x2 >= x1) { IncX1 = 1; IncX2 = 1; } + else { IncX1 = -1; IncX2 = -1; } + if (y2 >= y1) { IncY1 = 1; IncY2 = 1; } + else { IncY1 = -1; IncY2 = -1; } + if (dx >= dy) { + IncX1 = 0; + IncY2 = 0; + Den = dx; + Num = dx / 2; + NumAdd = dy; + NumPix = dx; + } + else { + IncX2 = 0; + IncY1 = 0; + Den = dy; + Num = dy / 2; + NumAdd = dx; + NumPix = dy; + } + + NumPix = Math.round(Q.LastPx + NumPix); + + var i = Q.LastPx; + for (; i < NumPix; i++) { + Num += NumAdd; + if (Num >= Den) { + Num -= Den; + x += IncX1; + y += IncY1; + } + x += IncX2; + y += IncY2; + } + Q.LastPx = NumPix; +} + +function CalcCross(V0, V1) { + var Cross = new Array(); + Cross[0] = V0[1]*V1[2] - V0[2]*V1[1]; + Cross[1] = V0[2]*V1[0] - V0[0]*V1[2]; + Cross[2] = V0[0]*V1[1] - V0[1]*V1[0]; + return Cross; +} + +function CalcNormal(V0, V1, V2) { + var A = new Array(); var B = new Array(); + for (var i = 0; i < 3; i++) { + A[i] = V0[i] - V1[i]; + B[i] = V2[i] - V1[i]; + } + A = CalcCross(A, B); + var Length = Math.sqrt(A[0]*A[0] + A[1]*A[1] + A[2]*A[2]); + for (var i = 0; i < 3; i++) A[i] = A[i] / Length; + A[3] = 1; + return A; +} + +function CreateP(X,Y,Z) { + this.V = [X,Y,Z,1]; +} + +// multiplies two matrices +function MMulti(M1, M2) { + var M = [[],[],[],[]]; + var i = 0; + var j = 0; + for (; i < 4; i++) { + j = 0; + for (; j < 4; j++) M[i][j] = M1[i][0] * M2[0][j] + M1[i][1] * M2[1][j] + M1[i][2] * M2[2][j] + M1[i][3] * M2[3][j]; + } + return M; +} + +//multiplies matrix with vector +function VMulti(M, V) { + var Vect = new Array(); + var i = 0; + for (;i < 4; i++) Vect[i] = M[i][0] * V[0] + M[i][1] * V[1] + M[i][2] * V[2] + M[i][3] * V[3]; + return Vect; +} + +function VMulti2(M, V) { + var Vect = new Array(); + var i = 0; + for (;i < 3; i++) Vect[i] = M[i][0] * V[0] + M[i][1] * V[1] + M[i][2] * V[2]; + return Vect; +} + +// add to matrices +function MAdd(M1, M2) { + var M = [[],[],[],[]]; + var i = 0; + var j = 0; + for (; i < 4; i++) { + j = 0; + for (; j < 4; j++) M[i][j] = M1[i][j] + M2[i][j]; + } + return M; +} + +function Translate(M, Dx, Dy, Dz) { + var T = [ + [1,0,0,Dx], + [0,1,0,Dy], + [0,0,1,Dz], + [0,0,0,1] + ]; + return MMulti(T, M); +} + +function RotateX(M, Phi) { + var a = Phi; + a *= Math.PI / 180; + var Cos = Math.cos(a); + var Sin = Math.sin(a); + var R = [ + [1,0,0,0], + [0,Cos,-Sin,0], + [0,Sin,Cos,0], + [0,0,0,1] + ]; + return MMulti(R, M); +} + +function RotateY(M, Phi) { + var a = Phi; + a *= Math.PI / 180; + var Cos = Math.cos(a); + var Sin = Math.sin(a); + var R = [ + [Cos,0,Sin,0], + [0,1,0,0], + [-Sin,0,Cos,0], + [0,0,0,1] + ]; + return MMulti(R, M); +} + +function RotateZ(M, Phi) { + var a = Phi; + a *= Math.PI / 180; + var Cos = Math.cos(a); + var Sin = Math.sin(a); + var R = [ + [Cos,-Sin,0,0], + [Sin,Cos,0,0], + [0,0,1,0], + [0,0,0,1] + ]; + return MMulti(R, M); +} + +function DrawQube() { + // calc current normals + var CurN = new Array(); + var i = 5; + Q.LastPx = 0; + for (; i > -1; i--) CurN[i] = VMulti2(MQube, Q.Normal[i]); + if (CurN[0][2] < 0) { + if (!Q.Line[0]) { DrawLine(Q[0], Q[1]); Q.Line[0] = true; }; + if (!Q.Line[1]) { DrawLine(Q[1], Q[2]); Q.Line[1] = true; }; + if (!Q.Line[2]) { DrawLine(Q[2], Q[3]); Q.Line[2] = true; }; + if (!Q.Line[3]) { DrawLine(Q[3], Q[0]); Q.Line[3] = true; }; + } + if (CurN[1][2] < 0) { + if (!Q.Line[2]) { DrawLine(Q[3], Q[2]); Q.Line[2] = true; }; + if (!Q.Line[9]) { DrawLine(Q[2], Q[6]); Q.Line[9] = true; }; + if (!Q.Line[6]) { DrawLine(Q[6], Q[7]); Q.Line[6] = true; }; + if (!Q.Line[10]) { DrawLine(Q[7], Q[3]); Q.Line[10] = true; }; + } + if (CurN[2][2] < 0) { + if (!Q.Line[4]) { DrawLine(Q[4], Q[5]); Q.Line[4] = true; }; + if (!Q.Line[5]) { DrawLine(Q[5], Q[6]); Q.Line[5] = true; }; + if (!Q.Line[6]) { DrawLine(Q[6], Q[7]); Q.Line[6] = true; }; + if (!Q.Line[7]) { DrawLine(Q[7], Q[4]); Q.Line[7] = true; }; + } + if (CurN[3][2] < 0) { + if (!Q.Line[4]) { DrawLine(Q[4], Q[5]); Q.Line[4] = true; }; + if (!Q.Line[8]) { DrawLine(Q[5], Q[1]); Q.Line[8] = true; }; + if (!Q.Line[0]) { DrawLine(Q[1], Q[0]); Q.Line[0] = true; }; + if (!Q.Line[11]) { DrawLine(Q[0], Q[4]); Q.Line[11] = true; }; + } + if (CurN[4][2] < 0) { + if (!Q.Line[11]) { DrawLine(Q[4], Q[0]); Q.Line[11] = true; }; + if (!Q.Line[3]) { DrawLine(Q[0], Q[3]); Q.Line[3] = true; }; + if (!Q.Line[10]) { DrawLine(Q[3], Q[7]); Q.Line[10] = true; }; + if (!Q.Line[7]) { DrawLine(Q[7], Q[4]); Q.Line[7] = true; }; + } + if (CurN[5][2] < 0) { + if (!Q.Line[8]) { DrawLine(Q[1], Q[5]); Q.Line[8] = true; }; + if (!Q.Line[5]) { DrawLine(Q[5], Q[6]); Q.Line[5] = true; }; + if (!Q.Line[9]) { DrawLine(Q[6], Q[2]); Q.Line[9] = true; }; + if (!Q.Line[1]) { DrawLine(Q[2], Q[1]); Q.Line[1] = true; }; + } + Q.Line = [false,false,false,false,false,false,false,false,false,false,false,false]; + Q.LastPx = 0; +} + +function Loop() { + if (Testing.LoopCount > Testing.LoopMax) return; + var TestingStr = String(Testing.LoopCount); + while (TestingStr.length < 3) TestingStr = "0" + TestingStr; + MTrans = Translate(I, -Q[8].V[0], -Q[8].V[1], -Q[8].V[2]); + MTrans = RotateX(MTrans, 1); + MTrans = RotateY(MTrans, 3); + MTrans = RotateZ(MTrans, 5); + MTrans = Translate(MTrans, Q[8].V[0], Q[8].V[1], Q[8].V[2]); + MQube = MMulti(MTrans, MQube); + var i = 8; + for (; i > -1; i--) { + Q[i].V = VMulti(MTrans, Q[i].V); + } + DrawQube(); + Testing.LoopCount++; + Loop(); +} + +function Init(CubeSize) { + // init/reset vars + Origin.V = [150,150,20,1]; + Testing.LoopCount = 0; + Testing.LoopMax = 50; + Testing.TimeMax = 0; + Testing.TimeAvg = 0; + Testing.TimeMin = 0; + Testing.TimeTemp = 0; + Testing.TimeTotal = 0; + Testing.Init = false; + + // transformation matrix + MTrans = [ + [1,0,0,0], + [0,1,0,0], + [0,0,1,0], + [0,0,0,1] + ]; + + // position information of qube + MQube = [ + [1,0,0,0], + [0,1,0,0], + [0,0,1,0], + [0,0,0,1] + ]; + + // entity matrix + I = [ + [1,0,0,0], + [0,1,0,0], + [0,0,1,0], + [0,0,0,1] + ]; + + // create qube + Q[0] = new CreateP(-CubeSize,-CubeSize, CubeSize); + Q[1] = new CreateP(-CubeSize, CubeSize, CubeSize); + Q[2] = new CreateP( CubeSize, CubeSize, CubeSize); + Q[3] = new CreateP( CubeSize,-CubeSize, CubeSize); + Q[4] = new CreateP(-CubeSize,-CubeSize,-CubeSize); + Q[5] = new CreateP(-CubeSize, CubeSize,-CubeSize); + Q[6] = new CreateP( CubeSize, CubeSize,-CubeSize); + Q[7] = new CreateP( CubeSize,-CubeSize,-CubeSize); + + // center of gravity + Q[8] = new CreateP(0, 0, 0); + + // anti-clockwise edge check + Q.Edge = [[0,1,2],[3,2,6],[7,6,5],[4,5,1],[4,0,3],[1,5,6]]; + + // calculate squad normals + Q.Normal = new Array(); + for (var i = 0; i < Q.Edge.length; i++) Q.Normal[i] = CalcNormal(Q[Q.Edge[i][0]].V, Q[Q.Edge[i][1]].V, Q[Q.Edge[i][2]].V); + + // line drawn ? + Q.Line = [false,false,false,false,false,false,false,false,false,false,false,false]; + + // create line pixels + Q.NumPx = 9 * 2 * CubeSize; + for (var i = 0; i < Q.NumPx; i++) CreateP(0,0,0); + + MTrans = Translate(MTrans, Origin.V[0], Origin.V[1], Origin.V[2]); + MQube = MMulti(MTrans, MQube); + + var i = 0; + for (; i < 9; i++) { + Q[i].V = VMulti(MTrans, Q[i].V); + } + DrawQube(); + Testing.Init = true; + Loop(); + + // Perform a simple sum-based verification. + var sum = 0; + for (var i = 0; i < Q.length; ++i) { + var vector = Q[i].V; + for (var j = 0; j < vector.length; ++j) + sum += vector[j]; + } + if (sum != validation[CubeSize]) + throw "Error: bad vector sum for CubeSize = " + CubeSize + "; expected " + validation[CubeSize] + " but got " + sum; +} + +for ( var i = 20; i <= 260000; i *= 2 ) { + Init(i); +} + +Q = null; +MTrans = null; +MQube = null; +I = null; +Origin = null; +Testing = null; +LoopTime = null; +DisplArea = null; + diff --git a/PerformanceTests/LongSpider/3d-morph.js b/PerformanceTests/LongSpider/3d-morph.js new file mode 100644 index 0000000..affd4c7 --- /dev/null +++ b/PerformanceTests/LongSpider/3d-morph.js @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +var loops = 3500 +var nx = 120 +var nz = 120 + +function morph(a, f) { + var PI2nx = Math.PI * 8/nx + var sin = Math.sin + var f30 = -(50 * sin(f*Math.PI*2)) + + for (var i = 0; i < nz; ++i) { + for (var j = 0; j < nx; ++j) { + a[3*(i*nx+j)+1] = sin((j-1) * PI2nx ) * -f30 + } + } +} + + +var a = Array() +for (var i=0; i < nx*nz*3; ++i) + a[i] = 0 + +for (var i = 0; i < loops; ++i) { + morph(a, i/loops) +} + +testOutput = 0; +for (var i = 0; i < nx; i++) + testOutput += a[3*(i*nx+i)+1]; +a = null; + +// This has to be an approximate test since ECMAscript doesn't formally specify +// what sin() returns. Even if it did specify something like for example what Java 7 +// says - that sin() has to return a value within 1 ulp of exact - then we still +// would not be able to do an exact test here since that would allow for just enough +// low-bit slop to create possibly big errors due to testOutput being a sum. +var expected = "-1"; +if (("" + testOutput).indexOf(expected) != 0) + throw "Error: bad test output: expected leading digit to be " + expected + " but got " + testOutput; diff --git a/PerformanceTests/LongSpider/3d-raytrace.js b/PerformanceTests/LongSpider/3d-raytrace.js new file mode 100644 index 0000000..6e503b6f --- /dev/null +++ b/PerformanceTests/LongSpider/3d-raytrace.js @@ -0,0 +1,450 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +function createVector(x,y,z) { + return new Array(x,y,z); +} + +function sqrLengthVector(self) { + return self[0] * self[0] + self[1] * self[1] + self[2] * self[2]; +} + +function lengthVector(self) { + return Math.sqrt(self[0] * self[0] + self[1] * self[1] + self[2] * self[2]); +} + +function addVector(self, v) { + self[0] += v[0]; + self[1] += v[1]; + self[2] += v[2]; + return self; +} + +function subVector(self, v) { + self[0] -= v[0]; + self[1] -= v[1]; + self[2] -= v[2]; + return self; +} + +function scaleVector(self, scale) { + self[0] *= scale; + self[1] *= scale; + self[2] *= scale; + return self; +} + +function normaliseVector(self) { + var len = Math.sqrt(self[0] * self[0] + self[1] * self[1] + self[2] * self[2]); + self[0] /= len; + self[1] /= len; + self[2] /= len; + return self; +} + +function add(v1, v2) { + return new Array(v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]); +} + +function sub(v1, v2) { + return new Array(v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]); +} + +function scalev(v1, v2) { + return new Array(v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2]); +} + +function dot(v1, v2) { + return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; +} + +function scale(v, scale) { + return [v[0] * scale, v[1] * scale, v[2] * scale]; +} + +function cross(v1, v2) { + return [v1[1] * v2[2] - v1[2] * v2[1], + v1[2] * v2[0] - v1[0] * v2[2], + v1[0] * v2[1] - v1[1] * v2[0]]; + +} + +function normalise(v) { + var len = lengthVector(v); + return [v[0] / len, v[1] / len, v[2] / len]; +} + +function transformMatrix(self, v) { + var vals = self; + var x = vals[0] * v[0] + vals[1] * v[1] + vals[2] * v[2] + vals[3]; + var y = vals[4] * v[0] + vals[5] * v[1] + vals[6] * v[2] + vals[7]; + var z = vals[8] * v[0] + vals[9] * v[1] + vals[10] * v[2] + vals[11]; + return [x, y, z]; +} + +function invertMatrix(self) { + var temp = new Array(16); + var tx = -self[3]; + var ty = -self[7]; + var tz = -self[11]; + for (h = 0; h < 3; h++) + for (v = 0; v < 3; v++) + temp[h + v * 4] = self[v + h * 4]; + for (i = 0; i < 11; i++) + self[i] = temp[i]; + self[3] = tx * self[0] + ty * self[1] + tz * self[2]; + self[7] = tx * self[4] + ty * self[5] + tz * self[6]; + self[11] = tx * self[8] + ty * self[9] + tz * self[10]; + return self; +} + + +// Triangle intersection using barycentric coord method +function Triangle(p1, p2, p3) { + var edge1 = sub(p3, p1); + var edge2 = sub(p2, p1); + var normal = cross(edge1, edge2); + if (Math.abs(normal[0]) > Math.abs(normal[1])) + if (Math.abs(normal[0]) > Math.abs(normal[2])) + this.axis = 0; + else + this.axis = 2; + else + if (Math.abs(normal[1]) > Math.abs(normal[2])) + this.axis = 1; + else + this.axis = 2; + var u = (this.axis + 1) % 3; + var v = (this.axis + 2) % 3; + var u1 = edge1[u]; + var v1 = edge1[v]; + + var u2 = edge2[u]; + var v2 = edge2[v]; + this.normal = normalise(normal); + this.nu = normal[u] / normal[this.axis]; + this.nv = normal[v] / normal[this.axis]; + this.nd = dot(normal, p1) / normal[this.axis]; + var det = u1 * v2 - v1 * u2; + this.eu = p1[u]; + this.ev = p1[v]; + this.nu1 = u1 / det; + this.nv1 = -v1 / det; + this.nu2 = v2 / det; + this.nv2 = -u2 / det; + this.material = [0.7, 0.7, 0.7]; +} + +Triangle.prototype.intersect = function(orig, dir, near, far) { + var u = (this.axis + 1) % 3; + var v = (this.axis + 2) % 3; + var d = dir[this.axis] + this.nu * dir[u] + this.nv * dir[v]; + var t = (this.nd - orig[this.axis] - this.nu * orig[u] - this.nv * orig[v]) / d; + if (t < near || t > far) + return null; + var Pu = orig[u] + t * dir[u] - this.eu; + var Pv = orig[v] + t * dir[v] - this.ev; + var a2 = Pv * this.nu1 + Pu * this.nv1; + if (a2 < 0) + return null; + var a3 = Pu * this.nu2 + Pv * this.nv2; + if (a3 < 0) + return null; + + if ((a2 + a3) > 1) + return null; + return t; +} + +function Scene(a_triangles) { + this.triangles = a_triangles; + this.lights = []; + this.ambient = [0,0,0]; + this.background = [0.8,0.8,1]; +} +var zero = new Array(0,0,0); + +Scene.prototype.intersect = function(origin, dir, near, far) { + var closest = null; + for (i = 0; i < this.triangles.length; i++) { + var triangle = this.triangles[i]; + var d = triangle.intersect(origin, dir, near, far); + if (d == null || d > far || d < near) + continue; + far = d; + closest = triangle; + } + + if (!closest) + return [this.background[0],this.background[1],this.background[2]]; + + var normal = closest.normal; + var hit = add(origin, scale(dir, far)); + if (dot(dir, normal) > 0) + normal = [-normal[0], -normal[1], -normal[2]]; + + var colour = null; + if (closest.shader) { + colour = closest.shader(closest, hit, dir); + } else { + colour = closest.material; + } + + // do reflection + var reflected = null; + if (colour.reflection > 0.001) { + var reflection = addVector(scale(normal, -2*dot(dir, normal)), dir); + reflected = this.intersect(hit, reflection, 0.0001, 1000000); + if (colour.reflection >= 0.999999) + return reflected; + } + + var l = [this.ambient[0], this.ambient[1], this.ambient[2]]; + for (var i = 0; i < this.lights.length; i++) { + var light = this.lights[i]; + var toLight = sub(light, hit); + var distance = lengthVector(toLight); + scaleVector(toLight, 1.0/distance); + distance -= 0.0001; + if (this.blocked(hit, toLight, distance)) + continue; + var nl = dot(normal, toLight); + if (nl > 0) + addVector(l, scale(light.colour, nl)); + } + l = scalev(l, colour); + if (reflected) { + l = addVector(scaleVector(l, 1 - colour.reflection), scaleVector(reflected, colour.reflection)); + } + return l; +} + +Scene.prototype.blocked = function(O, D, far) { + var near = 0.0001; + var closest = null; + for (i = 0; i < this.triangles.length; i++) { + var triangle = this.triangles[i]; + var d = triangle.intersect(O, D, near, far); + if (d == null || d > far || d < near) + continue; + return true; + } + + return false; +} + + +// this camera code is from notes i made ages ago, it is from *somewhere* -- i cannot remember where +// that somewhere is +function Camera(origin, lookat, up) { + var zaxis = normaliseVector(subVector(lookat, origin)); + var xaxis = normaliseVector(cross(up, zaxis)); + var yaxis = normaliseVector(cross(xaxis, subVector([0,0,0], zaxis))); + var m = new Array(16); + m[0] = xaxis[0]; m[1] = xaxis[1]; m[2] = xaxis[2]; + m[4] = yaxis[0]; m[5] = yaxis[1]; m[6] = yaxis[2]; + m[8] = zaxis[0]; m[9] = zaxis[1]; m[10] = zaxis[2]; + invertMatrix(m); + m[3] = 0; m[7] = 0; m[11] = 0; + this.origin = origin; + this.directions = new Array(4); + this.directions[0] = normalise([-0.7, 0.7, 1]); + this.directions[1] = normalise([ 0.7, 0.7, 1]); + this.directions[2] = normalise([ 0.7, -0.7, 1]); + this.directions[3] = normalise([-0.7, -0.7, 1]); + this.directions[0] = transformMatrix(m, this.directions[0]); + this.directions[1] = transformMatrix(m, this.directions[1]); + this.directions[2] = transformMatrix(m, this.directions[2]); + this.directions[3] = transformMatrix(m, this.directions[3]); +} + +Camera.prototype.generateRayPair = function(y) { + rays = new Array(new Object(), new Object()); + rays[0].origin = this.origin; + rays[1].origin = this.origin; + rays[0].dir = addVector(scale(this.directions[0], y), scale(this.directions[3], 1 - y)); + rays[1].dir = addVector(scale(this.directions[1], y), scale(this.directions[2], 1 - y)); + return rays; +} + +function renderRows(camera, scene, pixels, width, height, starty, stopy) { + for (var y = starty; y < stopy; y++) { + var rays = camera.generateRayPair(y / height); + for (var x = 0; x < width; x++) { + var xp = x / width; + var origin = addVector(scale(rays[0].origin, xp), scale(rays[1].origin, 1 - xp)); + var dir = normaliseVector(addVector(scale(rays[0].dir, xp), scale(rays[1].dir, 1 - xp))); + var l = scene.intersect(origin, dir); + pixels[y][x] = l; + } + } +} + +Camera.prototype.render = function(scene, pixels, width, height) { + var cam = this; + var row = 0; + renderRows(cam, scene, pixels, width, height, 0, height); +} + + + +function raytraceScene() +{ + var startDate = new Date().getTime(); + var numTriangles = 2 * 6; + var triangles = new Array();//numTriangles); + var tfl = createVector(-10, 10, -10); + var tfr = createVector( 10, 10, -10); + var tbl = createVector(-10, 10, 10); + var tbr = createVector( 10, 10, 10); + var bfl = createVector(-10, -10, -10); + var bfr = createVector( 10, -10, -10); + var bbl = createVector(-10, -10, 10); + var bbr = createVector( 10, -10, 10); + + // cube!!! + // front + var i = 0; + + triangles[i++] = new Triangle(tfl, tfr, bfr); + triangles[i++] = new Triangle(tfl, bfr, bfl); + // back + triangles[i++] = new Triangle(tbl, tbr, bbr); + triangles[i++] = new Triangle(tbl, bbr, bbl); + // triangles[i-1].material = [0.7,0.2,0.2]; + // triangles[i-1].material.reflection = 0.8; + // left + triangles[i++] = new Triangle(tbl, tfl, bbl); + // triangles[i-1].reflection = 0.6; + triangles[i++] = new Triangle(tfl, bfl, bbl); + // triangles[i-1].reflection = 0.6; + // right + triangles[i++] = new Triangle(tbr, tfr, bbr); + triangles[i++] = new Triangle(tfr, bfr, bbr); + // top + triangles[i++] = new Triangle(tbl, tbr, tfr); + triangles[i++] = new Triangle(tbl, tfr, tfl); + // bottom + triangles[i++] = new Triangle(bbl, bbr, bfr); + triangles[i++] = new Triangle(bbl, bfr, bfl); + + //Floor!!!! + var green = createVector(0.0, 0.4, 0.0); + var grey = createVector(0.4, 0.4, 0.4); + grey.reflection = 1.0; + var floorShader = function(tri, pos, view) { + var x = ((pos[0]/32) % 2 + 2) % 2; + var z = ((pos[2]/32 + 0.3) % 2 + 2) % 2; + if (x < 1 != z < 1) { + //in the real world we use the fresnel term... + // var angle = 1-dot(view, tri.normal); + // angle *= angle; + // angle *= angle; + // angle *= angle; + //grey.reflection = angle; + return grey; + } else + return green; + } + var ffl = createVector(-1000, -30, -1000); + var ffr = createVector( 1000, -30, -1000); + var fbl = createVector(-1000, -30, 1000); + var fbr = createVector( 1000, -30, 1000); + triangles[i++] = new Triangle(fbl, fbr, ffr); + triangles[i-1].shader = floorShader; + triangles[i++] = new Triangle(fbl, ffr, ffl); + triangles[i-1].shader = floorShader; + + var _scene = new Scene(triangles); + _scene.lights[0] = createVector(20, 38, -22); + _scene.lights[0].colour = createVector(0.7, 0.3, 0.3); + _scene.lights[1] = createVector(-23, 40, 17); + _scene.lights[1].colour = createVector(0.7, 0.3, 0.3); + _scene.lights[2] = createVector(23, 20, 17); + _scene.lights[2].colour = createVector(0.7, 0.7, 0.7); + _scene.ambient = createVector(0.1, 0.1, 0.1); + // _scene.background = createVector(0.7, 0.7, 1.0); + + var size = 30; + var pixels = new Array(); + for (var y = 0; y < size; y++) { + pixels[y] = new Array(); + for (var x = 0; x < size; x++) { + pixels[y][x] = 0; + } + } + + var _camera = new Camera(createVector(-40, 40, 40), createVector(0, 0, 0), createVector(0, 1, 0)); + _camera.render(_scene, pixels, size, size); + + return pixels; +} + +function arrayToCanvasCommands(pixels) +{ + var s = '\nvar pixels = ['; + var size = 30; + for (var y = 0; y < size; y++) { + s += "["; + for (var x = 0; x < size; x++) { + s += "[" + pixels[y][x] + "],"; + } + s+= "],"; + } + s += '];\n var canvas = document.getElementById("renderCanvas").getContext("2d");\n\ +\n\ +\n\ + var size = 30;\n\ + canvas.fillStyle = "red";\n\ + canvas.fillRect(0, 0, size, size);\n\ + canvas.scale(1, -1);\n\ + canvas.translate(0, -size);\n\ +\n\ + if (!canvas.setFillColor)\n\ + canvas.setFillColor = function(r, g, b, a) {\n\ + this.fillStyle = "rgb("+[Math.floor(r * 255), Math.floor(g * 255), Math.floor(b * 255)]+")";\n\ + }\n\ +\n\ +for (var y = 0; y < size; y++) {\n\ + for (var x = 0; x < size; x++) {\n\ + var l = pixels[y][x];\n\ + canvas.setFillColor(l[0], l[1], l[2], 1);\n\ + canvas.fillRect(x, y, 1, 1);\n\ + }\n\ +}'; + + return s; +} + +for (var __i = 0; __i < 300; ++__i) { + testOutput = arrayToCanvasCommands(raytraceScene()); + + var expectedLength = 20970; + + if (testOutput.length != expectedLength) + throw "Error: bad result: expected length " + expectedLength + " but got " + testOutput.length; +} + + diff --git a/PerformanceTests/LongSpider/access-binary-trees.js b/PerformanceTests/LongSpider/access-binary-trees.js new file mode 100644 index 0000000..9d47815 --- /dev/null +++ b/PerformanceTests/LongSpider/access-binary-trees.js @@ -0,0 +1,54 @@ +/* The Great Computer Language Shootout + http://shootout.alioth.debian.org/ + contributed by Isaac Gouy */ + +function TreeNode(left,right,item){ + this.left = left; + this.right = right; + this.item = item; +} + +TreeNode.prototype.itemCheck = function(){ + if (this.left==null) return this.item; + else return this.item + this.left.itemCheck() - this.right.itemCheck(); +} + +function bottomUpTree(item,depth){ + if (depth>0){ + return new TreeNode( + bottomUpTree(2*item-1, depth-1) + ,bottomUpTree(2*item, depth-1) + ,item + ); + } + else { + return new TreeNode(null,null,item); + } +} + +var ret = 0; + +for ( var n = 4; n <= 16; n += 1 ) { + var minDepth = 4; + var maxDepth = Math.max(minDepth + 2, n); + var stretchDepth = maxDepth + 1; + + var check = bottomUpTree(0,stretchDepth).itemCheck(); + + var longLivedTree = bottomUpTree(0,maxDepth); + for (var depth=minDepth; depth<=maxDepth; depth+=2){ + var iterations = 1 << (maxDepth - depth + minDepth); + + check = 0; + for (var i=1; i<=iterations; i++){ + check += bottomUpTree(i,depth).itemCheck(); + check += bottomUpTree(-i,depth).itemCheck(); + } + } + + ret += longLivedTree.itemCheck(); +} + +var expected = -13; +if (ret != expected) + throw "ERROR: bad result: expected " + expected + " but got " + ret; diff --git a/PerformanceTests/LongSpider/access-fannkuch.js b/PerformanceTests/LongSpider/access-fannkuch.js new file mode 100644 index 0000000..0fb0f47 --- /dev/null +++ b/PerformanceTests/LongSpider/access-fannkuch.js @@ -0,0 +1,70 @@ +/* The Great Computer Language Shootout + http://shootout.alioth.debian.org/ + contributed by Isaac Gouy */ + +function fannkuch(n) { + var check = 0; + var perm = Array(n); + var perm1 = Array(n); + var count = Array(n); + var maxPerm = Array(n); + var maxFlipsCount = 0; + var m = n - 1; + + for (var i = 0; i < n; i++) perm1[i] = i; + var r = n; + + while (true) { + // write-out the first 30 permutations + if (check < 30){ + var s = ""; + for(var i=0; i> 1; + for (var i = 0; i < k2; i++) { + var temp = perm[i]; perm[i] = perm[k - i]; perm[k - i] = temp; + } + flipsCount++; + } + + if (flipsCount > maxFlipsCount) { + maxFlipsCount = flipsCount; + for (var i = 0; i < n; i++) maxPerm[i] = perm1[i]; + } + } + + while (true) { + if (r == n) return maxFlipsCount; + var perm0 = perm1[0]; + var i = 0; + while (i < r) { + var j = i + 1; + perm1[i] = perm1[j]; + i = j; + } + perm1[r] = perm0; + + count[r] = count[r] - 1; + if (count[r] > 0) break; + r++; + } + } +} + +var n = 10; +var ret = fannkuch(n); + +var expected = 38; +if (ret != expected) + throw "ERROR: bad result: expected " + expected + " but got " + ret; + diff --git a/PerformanceTests/LongSpider/access-nbody.js b/PerformanceTests/LongSpider/access-nbody.js new file mode 100644 index 0000000..de3f6fe --- /dev/null +++ b/PerformanceTests/LongSpider/access-nbody.js @@ -0,0 +1,174 @@ +/* The Great Computer Language Shootout + http://shootout.alioth.debian.org/ + contributed by Isaac Gouy */ + +var PI = 3.141592653589793; +var SOLAR_MASS = 4 * PI * PI; +var DAYS_PER_YEAR = 365.24; + +function Body(x,y,z,vx,vy,vz,mass){ + this.x = x; + this.y = y; + this.z = z; + this.vx = vx; + this.vy = vy; + this.vz = vz; + this.mass = mass; +} + +Body.prototype.offsetMomentum = function(px,py,pz) { + this.vx = -px / SOLAR_MASS; + this.vy = -py / SOLAR_MASS; + this.vz = -pz / SOLAR_MASS; + return this; +} + +function Jupiter(){ + return new Body( + 4.84143144246472090e+00, + -1.16032004402742839e+00, + -1.03622044471123109e-01, + 1.66007664274403694e-03 * DAYS_PER_YEAR, + 7.69901118419740425e-03 * DAYS_PER_YEAR, + -6.90460016972063023e-05 * DAYS_PER_YEAR, + 9.54791938424326609e-04 * SOLAR_MASS + ); +} + +function Saturn(){ + return new Body( + 8.34336671824457987e+00, + 4.12479856412430479e+00, + -4.03523417114321381e-01, + -2.76742510726862411e-03 * DAYS_PER_YEAR, + 4.99852801234917238e-03 * DAYS_PER_YEAR, + 2.30417297573763929e-05 * DAYS_PER_YEAR, + 2.85885980666130812e-04 * SOLAR_MASS + ); +} + +function Uranus(){ + return new Body( + 1.28943695621391310e+01, + -1.51111514016986312e+01, + -2.23307578892655734e-01, + 2.96460137564761618e-03 * DAYS_PER_YEAR, + 2.37847173959480950e-03 * DAYS_PER_YEAR, + -2.96589568540237556e-05 * DAYS_PER_YEAR, + 4.36624404335156298e-05 * SOLAR_MASS + ); +} + +function Neptune(){ + return new Body( + 1.53796971148509165e+01, + -2.59193146099879641e+01, + 1.79258772950371181e-01, + 2.68067772490389322e-03 * DAYS_PER_YEAR, + 1.62824170038242295e-03 * DAYS_PER_YEAR, + -9.51592254519715870e-05 * DAYS_PER_YEAR, + 5.15138902046611451e-05 * SOLAR_MASS + ); +} + +function Sun(){ + return new Body(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, SOLAR_MASS); +} + + +function NBodySystem(bodies){ + this.bodies = bodies; + var px = 0.0; + var py = 0.0; + var pz = 0.0; + var size = this.bodies.length; + for (var i=0; i0){ + for (var i=1; i<=prefixWidth; i++) s = " " + s; + } + return s; +} + +function nsieve(m, isPrime){ + var i, k, count; + + for (i=2; i<=m; i++) { isPrime[i] = true; } + count = 0; + + for (i=2; i<=m; i++){ + if (isPrime[i]) { + for (k=i+i; k<=m; k+=i) isPrime[k] = false; + count++; + } + } + return count; +} + +function sieve() { + var sum = 0; + for (var i = 1; i <= 10; i++ ) { + var m = (1<> ((b << 1) & 14)); +c += 3 & (bi3b >> ((b >> 2) & 14)); +c += 3 & (bi3b >> ((b >> 5) & 6)); +return c; + +/* +lir4,0xE994; 9 instructions, no memory access, minimal register dependence, 6 shifts, 2 adds, 1 inline assign +rlwinmr5,r3,1,28,30 +rlwinmr6,r3,30,28,30 +rlwinmr7,r3,27,29,30 +rlwnmr8,r4,r5,30,31 +rlwnmr9,r4,r6,30,31 +rlwnmr10,r4,r7,30,31 +addr3,r8,r9 +addr3,r3,r10 +*/ +} + + +function TimeFunc(func) { +var x, y, t; +var sum = 0; +for(var x=0; x<50000; x++) +for(var y=0; y<256; y++) sum += func(y); +return sum; +} + +sum = TimeFunc(fast3bitlookup); + +var expected = 51200000; +if (sum != expected) + throw "ERROR: bad result: expected " + expected + " but got " + sum; diff --git a/PerformanceTests/LongSpider/bitops-bits-in-byte.js b/PerformanceTests/LongSpider/bitops-bits-in-byte.js new file mode 100644 index 0000000..75711eb --- /dev/null +++ b/PerformanceTests/LongSpider/bitops-bits-in-byte.js @@ -0,0 +1,30 @@ +// Copyright (c) 2004 by Arthur Langereis (arthur_ext at domain xfinitegames, tld com) + + +var result = 0; + +// 1 op = 2 assigns, 16 compare/branches, 8 ANDs, (0-8) ADDs, 8 SHLs +// O(n) +function bitsinbyte(b) { +var m = 1, c = 0; +while(m<0x100) { +if(b & m) c++; +m <<= 1; +} +return c; +} + +function TimeFunc(func) { +var x, y, t; +var sum = 0; +for(var x=0; x<35000; x++) +for(var y=0; y<256; y++) sum += func(y); +return sum; +} + +result = TimeFunc(bitsinbyte); + +var expected = 35840000; +if (result != expected) + throw "ERROR: bad result: expected " + expected + " but got " + result; + diff --git a/PerformanceTests/LongSpider/bitops-nsieve-bits.js b/PerformanceTests/LongSpider/bitops-nsieve-bits.js new file mode 100644 index 0000000..547d2d5 --- /dev/null +++ b/PerformanceTests/LongSpider/bitops-nsieve-bits.js @@ -0,0 +1,42 @@ +// The Great Computer Language Shootout +// http://shootout.alioth.debian.org +// +// Contributed by Ian Osgood + +function pad(n,width) { + var s = n.toString(); + while (s.length < width) s = ' ' + s; + return s; +} + +function primes(isPrime, n) { + var i, count = 0, m = 10000<>5; + + for (i=0; i>5] & 1<<(i&31)) { + for (var j=i+i; j>5] &= ~(1<<(j&31)); + count++; + } +} + +function sieve() { + for (var i = 4; i <= 11; i++) { + var isPrime = new Array((10000<>5); + primes(isPrime, i); + } + return isPrime; +} + +var result = sieve(); + +var sum = 0; +for (var i = 0; i < result.length; ++i) + sum += result[i]; + +var expected = -116331605199501; +if (sum != expected) + throw "ERROR: bad result: expected " + expected + " but got " + sum; + diff --git a/PerformanceTests/LongSpider/controlflow-recursive.js b/PerformanceTests/LongSpider/controlflow-recursive.js new file mode 100644 index 0000000..ab92bc6 --- /dev/null +++ b/PerformanceTests/LongSpider/controlflow-recursive.js @@ -0,0 +1,32 @@ +// The Computer Language Shootout +// http://shootout.alioth.debian.org/ +// contributed by Isaac Gouy + +function ack(m,n){ + if (m==0) { return n+1; } + if (n==0) { return ack(m-1,1); } + return ack(m-1, ack(m,n-1) ); +} + +function fib(n) { + if (n < 2){ return 1; } + return fib(n-2) + fib(n-1); +} + +function tak(x,y,z) { + if (y >= x) return z; + return tak(tak(x-1,y,z), tak(y-1,z,x), tak(z-1,x,y)); +} + +var result = 0; + +for ( var i = 3; i <= 9; i++ ) { + result += ack(3,i); + result += fib(17.0+i); + result += tak(3*i+3,2*i+2,i+1); +} + +var expected = 504699; +if (result != expected) + throw "ERROR: bad result: expected " + expected + " but got " + result; + diff --git a/PerformanceTests/LongSpider/crypto-aes.js b/PerformanceTests/LongSpider/crypto-aes.js new file mode 100644 index 0000000..ce1a520 --- /dev/null +++ b/PerformanceTests/LongSpider/crypto-aes.js @@ -0,0 +1,429 @@ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +/* + * AES Cipher function: encrypt 'input' with Rijndael algorithm + * + * takes byte-array 'input' (16 bytes) + * 2D byte-array key schedule 'w' (Nr+1 x Nb bytes) + * + * applies Nr rounds (10/12/14) using key schedule w for 'add round key' stage + * + * returns byte-array encrypted value (16 bytes) + */ +function Cipher(input, w) { // main Cipher function [§5.1] + var Nb = 4; // block size (in words): no of columns in state (fixed at 4 for AES) + var Nr = w.length/Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys + + var state = [[],[],[],[]]; // initialise 4xNb byte-array 'state' with input [§3.4] + for (var i=0; i<4*Nb; i++) state[i%4][Math.floor(i/4)] = input[i]; + + state = AddRoundKey(state, w, 0, Nb); + + for (var round=1; round 6 && i%Nk == 4) { + temp = SubWord(temp); + } + for (var t=0; t<4; t++) w[i][t] = w[i-Nk][t] ^ temp[t]; + } + + return w; +} + +function SubWord(w) { // apply SBox to 4-byte word w + for (var i=0; i<4; i++) w[i] = Sbox[w[i]]; + return w; +} + +function RotWord(w) { // rotate 4-byte word w left by one byte + w[4] = w[0]; + for (var i=0; i<4; i++) w[i] = w[i+1]; + return w; +} + + +// Sbox is pre-computed multiplicative inverse in GF(2^8) used in SubBytes and KeyExpansion [§5.1.1] +var Sbox = [0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76, + 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0, + 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15, + 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75, + 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84, + 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf, + 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8, + 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2, + 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73, + 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb, + 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79, + 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08, + 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a, + 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e, + 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf, + 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16]; + +// Rcon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [§5.2] +var Rcon = [ [0x00, 0x00, 0x00, 0x00], + [0x01, 0x00, 0x00, 0x00], + [0x02, 0x00, 0x00, 0x00], + [0x04, 0x00, 0x00, 0x00], + [0x08, 0x00, 0x00, 0x00], + [0x10, 0x00, 0x00, 0x00], + [0x20, 0x00, 0x00, 0x00], + [0x40, 0x00, 0x00, 0x00], + [0x80, 0x00, 0x00, 0x00], + [0x1b, 0x00, 0x00, 0x00], + [0x36, 0x00, 0x00, 0x00] ]; + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +/* + * Use AES to encrypt 'plaintext' with 'password' using 'nBits' key, in 'Counter' mode of operation + * - see http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + * for each block + * - outputblock = cipher(counter, key) + * - cipherblock = plaintext xor outputblock + */ +function AESEncryptCtr(plaintext, password, nBits) { + if (!(nBits==128 || nBits==192 || nBits==256)) return ''; // standard allows 128/192/256 bit keys + + // for this example script, generate the key by applying Cipher to 1st 16/24/32 chars of password; + // for real-world applications, a more secure approach would be to hash the password e.g. with SHA-1 + var nBytes = nBits/8; // no bytes in key + var pwBytes = new Array(nBytes); + for (var i=0; i>> i*8) & 0xff; + for (var i=0; i<4; i++) counterBlock[i+4] = (nonce/0x100000000 >>> i*8) & 0xff; + + // generate key schedule - an expansion of the key into distinct Key Rounds for each round + var keySchedule = KeyExpansion(key); + + var blockCount = Math.ceil(plaintext.length/blockSize); + var ciphertext = new Array(blockCount); // ciphertext as array of strings + + for (var b=0; b>> c*8) & 0xff; + for (var c=0; c<4; c++) counterBlock[15-c-4] = (b/0x100000000 >>> c*8) + + var cipherCntr = Cipher(counterBlock, keySchedule); // -- encrypt counter block -- + + // calculate length of final block: + var blockLength = b>> c*8) & 0xff; + for (var c=0; c<4; c++) counterBlock[15-c-4] = ((b/0x100000000-1) >>> c*8) & 0xff; + + var cipherCntr = Cipher(counterBlock, keySchedule); // encrypt counter block + + ciphertext[b] = unescCtrlChars(ciphertext[b]); + + var pt = ''; + for (var i=0; i>18 & 0x3f; + h2 = bits>>12 & 0x3f; + h3 = bits>>6 & 0x3f; + h4 = bits & 0x3f; + + // end of string? index to '=' in b64 + if (isNaN(o3)) h4 = 64; + if (isNaN(o2)) h3 = 64; + + // use hexets to index into b64, and append result to encoded string + enc += b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4); + } while (i < str.length); + + return enc; +} + +function decodeBase64(str) { + var o1, o2, o3, h1, h2, h3, h4, bits, i=0, enc=''; + + do { // unpack four hexets into three octets using index points in b64 + h1 = b64.indexOf(str.charAt(i++)); + h2 = b64.indexOf(str.charAt(i++)); + h3 = b64.indexOf(str.charAt(i++)); + h4 = b64.indexOf(str.charAt(i++)); + + bits = h1<<18 | h2<<12 | h3<<6 | h4; + + o1 = bits>>16 & 0xff; + o2 = bits>>8 & 0xff; + o3 = bits & 0xff; + + if (h3 == 64) enc += String.fromCharCode(o1); + else if (h4 == 64) enc += String.fromCharCode(o1, o2); + else enc += String.fromCharCode(o1, o2, o3); + } while (i < str.length); + + return decodeUTF8(enc); // decode UTF-8 byte-array back to Unicode +} + +function encodeUTF8(str) { // encode multi-byte string into utf-8 multiple single-byte characters + str = str.replace( + /[\u0080-\u07ff]/g, // U+0080 - U+07FF = 2-byte chars + function(c) { + var cc = c.charCodeAt(0); + return String.fromCharCode(0xc0 | cc>>6, 0x80 | cc&0x3f); } + ); + str = str.replace( + /[\u0800-\uffff]/g, // U+0800 - U+FFFF = 3-byte chars + function(c) { + var cc = c.charCodeAt(0); + return String.fromCharCode(0xe0 | cc>>12, 0x80 | cc>>6&0x3F, 0x80 | cc&0x3f); } + ); + return str; +} + +function decodeUTF8(str) { // decode utf-8 encoded string back into multi-byte characters + str = str.replace( + /[\u00c0-\u00df][\u0080-\u00bf]/g, // 2-byte chars + function(c) { + var cc = (c.charCodeAt(0)&0x1f)<<6 | c.charCodeAt(1)&0x3f; + return String.fromCharCode(cc); } + ); + str = str.replace( + /[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g, // 3-byte chars + function(c) { + var cc = (c.charCodeAt(0)&0x0f)<<12 | (c.charCodeAt(1)&0x3f<<6) | c.charCodeAt(2)&0x3f; + return String.fromCharCode(cc); } + ); + return str; +} + + +function byteArrayToHexStr(b) { // convert byte array to hex string for displaying test vectors + var s = ''; + for (var i=0; i> 5] |= 0x80 << ((len) % 32); + x[(((len + 64) >>> 9) << 4) + 14] = len; + + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + + for(var i = 0; i < x.length; i += 16) + { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + + a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); + d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); + c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); + b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); + a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); + d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); + c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); + b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); + a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); + d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); + c = md5_ff(c, d, a, b, x[i+10], 17, -42063); + b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); + a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); + d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); + c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); + b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); + + a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); + d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); + c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); + b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); + a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); + d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); + c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); + b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); + a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); + d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); + c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); + b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); + a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); + d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); + c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); + b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); + + a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); + d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); + c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); + b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); + a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); + d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); + c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); + b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); + a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); + d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); + c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); + b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); + a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); + d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); + c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); + b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); + + a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); + d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); + c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); + b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); + a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); + d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); + c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); + b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); + a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); + d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); + c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); + b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); + a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); + d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); + c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); + b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + } + return Array(a, b, c, d); + +} + +/* + * These functions implement the four basic operations the algorithm uses. + */ +function md5_cmn(q, a, b, x, s, t) +{ + return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); +} +function md5_ff(a, b, c, d, x, s, t) +{ + return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); +} +function md5_gg(a, b, c, d, x, s, t) +{ + return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); +} +function md5_hh(a, b, c, d, x, s, t) +{ + return md5_cmn(b ^ c ^ d, a, b, x, s, t); +} +function md5_ii(a, b, c, d, x, s, t) +{ + return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); +} + +/* + * Calculate the HMAC-MD5, of a key and some data + */ +function core_hmac_md5(key, data) +{ + var bkey = str2binl(key); + if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz); + + var ipad = Array(16), opad = Array(16); + for(var i = 0; i < 16; i++) + { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + + var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz); + return core_md5(opad.concat(hash), 512 + 128); +} + +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +function safe_add(x, y) +{ + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} + +/* + * Bitwise rotate a 32-bit number to the left. + */ +function bit_rol(num, cnt) +{ + return (num << cnt) | (num >>> (32 - cnt)); +} + +/* + * Convert a string to an array of little-endian words + * If chrsz is ASCII, characters >255 have their hi-byte silently ignored. + */ +function str2binl(str) +{ + var bin = Array(); + var mask = (1 << chrsz) - 1; + for(var i = 0; i < str.length * chrsz; i += chrsz) + bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32); + return bin; +} + +/* + * Convert an array of little-endian words to a string + */ +function binl2str(bin) +{ + var str = ""; + var mask = (1 << chrsz) - 1; + for(var i = 0; i < bin.length * 32; i += chrsz) + str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask); + return str; +} + +/* + * Convert an array of little-endian words to a hex string. + */ +function binl2hex(binarray) +{ + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var str = ""; + for(var i = 0; i < binarray.length * 4; i++) + { + str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) + + hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF); + } + return str; +} + +/* + * Convert an array of little-endian words to a base-64 string + */ +function binl2b64(binarray) +{ + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var str = ""; + for(var i = 0; i < binarray.length * 4; i += 3) + { + var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16) + | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 ) + | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF); + for(var j = 0; j < 4; j++) + { + if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; + else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); + } + } + return str; +} + +var plainText = "Rebellious subjects, enemies to peace,\n\ +Profaners of this neighbour-stained steel,--\n\ +Will they not hear? What, ho! you men, you beasts,\n\ +That quench the fire of your pernicious rage\n\ +With purple fountains issuing from your veins,\n\ +On pain of torture, from those bloody hands\n\ +Throw your mistemper'd weapons to the ground,\n\ +And hear the sentence of your moved prince.\n\ +Three civil brawls, bred of an airy word,\n\ +By thee, old Capulet, and Montague,\n\ +Have thrice disturb'd the quiet of our streets,\n\ +And made Verona's ancient citizens\n\ +Cast by their grave beseeming ornaments,\n\ +To wield old partisans, in hands as old,\n\ +Canker'd with peace, to part your canker'd hate:\n\ +If ever you disturb our streets again,\n\ +Your lives shall pay the forfeit of the peace.\n\ +For this time, all the rest depart away:\n\ +You Capulet; shall go along with me:\n\ +And, Montague, come you this afternoon,\n\ +To know our further pleasure in this case,\n\ +To old Free-town, our common judgment-place.\n\ +Once more, on pain of death, all men depart." + +for (var i = 0; i <9; i++) { + plainText += plainText; +} + +for (var i = 0 ; i < 40; ++i) { + var md5Output = hex_md5(plainText); + + var expected = "3dfe3a86e990dc8bf5868823e917556e"; + + if (md5Output != expected) + throw "ERROR: bad result: expected " + expected + " but got " + md5Output; +} + + diff --git a/PerformanceTests/LongSpider/crypto-sha1.js b/PerformanceTests/LongSpider/crypto-sha1.js new file mode 100644 index 0000000..e1be516 --- /dev/null +++ b/PerformanceTests/LongSpider/crypto-sha1.js @@ -0,0 +1,231 @@ +/* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined + * in FIPS PUB 180-1 + * Version 2.1a Copyright Paul Johnston 2000 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for details. + */ + +/* + * Configurable variables. You may need to tweak these to be compatible with + * the server-side, but the defaults work in most cases. + */ +var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ +var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ +var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ + +/* + * These are the functions you'll usually want to call + * They take string arguments and return either hex or base-64 encoded strings + */ +function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));} +function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));} +function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));} +function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));} +function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));} +function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));} + +/* + * Perform a simple self-test to see if the VM is working + */ +function sha1_vm_test() +{ + return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d"; +} + +/* + * Calculate the SHA-1 of an array of big-endian words, and a bit length + */ +function core_sha1(x, len) +{ + /* append padding */ + x[len >> 5] |= 0x80 << (24 - len % 32); + x[((len + 64 >> 9) << 4) + 15] = len; + + var w = Array(80); + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + var e = -1009589776; + + for(var i = 0; i < x.length; i += 16) + { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + var olde = e; + + for(var j = 0; j < 80; j++) + { + if(j < 16) w[j] = x[i + j]; + else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); + var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), + safe_add(safe_add(e, w[j]), sha1_kt(j))); + e = d; + d = c; + c = rol(b, 30); + b = a; + a = t; + } + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + e = safe_add(e, olde); + } + return Array(a, b, c, d, e); + +} + +/* + * Perform the appropriate triplet combination function for the current + * iteration + */ +function sha1_ft(t, b, c, d) +{ + if(t < 20) return (b & c) | ((~b) & d); + if(t < 40) return b ^ c ^ d; + if(t < 60) return (b & c) | (b & d) | (c & d); + return b ^ c ^ d; +} + +/* + * Determine the appropriate additive constant for the current iteration + */ +function sha1_kt(t) +{ + return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : + (t < 60) ? -1894007588 : -899497514; +} + +/* + * Calculate the HMAC-SHA1 of a key and some data + */ +function core_hmac_sha1(key, data) +{ + var bkey = str2binb(key); + if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz); + + var ipad = Array(16), opad = Array(16); + for(var i = 0; i < 16; i++) + { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + + var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz); + return core_sha1(opad.concat(hash), 512 + 160); +} + +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +function safe_add(x, y) +{ + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} + +/* + * Bitwise rotate a 32-bit number to the left. + */ +function rol(num, cnt) +{ + return (num << cnt) | (num >>> (32 - cnt)); +} + +/* + * Convert an 8-bit or 16-bit string to an array of big-endian words + * In 8-bit function, characters >255 have their hi-byte silently ignored. + */ +function str2binb(str) +{ + var bin = Array(); + var mask = (1 << chrsz) - 1; + for(var i = 0; i < str.length * chrsz; i += chrsz) + bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32); + return bin; +} + +/* + * Convert an array of big-endian words to a string + */ +function binb2str(bin) +{ + var str = ""; + var mask = (1 << chrsz) - 1; + for(var i = 0; i < bin.length * 32; i += chrsz) + str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask); + return str; +} + +/* + * Convert an array of big-endian words to a hex string. + */ +function binb2hex(binarray) +{ + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var str = ""; + for(var i = 0; i < binarray.length * 4; i++) + { + str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) + + hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF); + } + return str; +} + +/* + * Convert an array of big-endian words to a base-64 string + */ +function binb2b64(binarray) +{ + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var str = ""; + for(var i = 0; i < binarray.length * 4; i += 3) + { + var triplet = (((binarray[i >> 2] >> 8 * (3 - i %4)) & 0xFF) << 16) + | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 ) + | ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF); + for(var j = 0; j < 4; j++) + { + if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; + else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); + } + } + return str; +} + + +var plainText = "Two households, both alike in dignity,\n\ +In fair Verona, where we lay our scene,\n\ +From ancient grudge break to new mutiny,\n\ +Where civil blood makes civil hands unclean.\n\ +From forth the fatal loins of these two foes\n\ +A pair of star-cross'd lovers take their life;\n\ +Whole misadventured piteous overthrows\n\ +Do with their death bury their parents' strife.\n\ +The fearful passage of their death-mark'd love,\n\ +And the continuance of their parents' rage,\n\ +Which, but their children's end, nought could remove,\n\ +Is now the two hours' traffic of our stage;\n\ +The which if you with patient ears attend,\n\ +What here shall miss, our toil shall strive to mend."; + +for (var i = 0; i <12; i++) { + plainText += plainText; +} + +for (var i = 0; i < 10; ++i) { + var sha1Output = hex_sha1(plainText); + + var expected = "716b0011ef72c5b3f12733109d82ad5d66c788fc"; + if (sha1Output != expected) + throw "ERROR: bad result: expected " + expected + " but got " + sha1Output; +} + diff --git a/PerformanceTests/LongSpider/date-format-tofte.js b/PerformanceTests/LongSpider/date-format-tofte.js new file mode 100644 index 0000000..e193ced --- /dev/null +++ b/PerformanceTests/LongSpider/date-format-tofte.js @@ -0,0 +1,301 @@ +function arrayExists(array, x) { + for (var i = 0; i < array.length; i++) { + if (array[i] == x) return true; + } + return false; +} + +Date.prototype.formatDate = function (input,time) { + // formatDate : + // a PHP date like function, for formatting date strings + // See: http://www.php.net/date + // + // input : format string + // time : epoch time (seconds, and optional) + // + // if time is not passed, formatting is based on + // the current "this" date object's set time. + // + // supported: + // a, A, B, d, D, F, g, G, h, H, i, j, l (lowercase L), L, + // m, M, n, O, r, s, S, t, U, w, W, y, Y, z + // + // unsupported: + // I (capital i), T, Z + + var switches = ["a", "A", "B", "d", "D", "F", "g", "G", "h", "H", + "i", "j", "l", "L", "m", "M", "n", "O", "r", "s", + "S", "t", "U", "w", "W", "y", "Y", "z"]; + var daysLong = ["Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday"]; + var daysShort = ["Sun", "Mon", "Tue", "Wed", + "Thu", "Fri", "Sat"]; + var monthsShort = ["Jan", "Feb", "Mar", "Apr", + "May", "Jun", "Jul", "Aug", "Sep", + "Oct", "Nov", "Dec"]; + var monthsLong = ["January", "February", "March", "April", + "May", "June", "July", "August", "September", + "October", "November", "December"]; + var daysSuffix = ["st", "nd", "rd", "th", "th", "th", "th", // 1st - 7th + "th", "th", "th", "th", "th", "th", "th", // 8th - 14th + "th", "th", "th", "th", "th", "th", "st", // 15th - 21st + "nd", "rd", "th", "th", "th", "th", "th", // 22nd - 28th + "th", "th", "st"]; // 29th - 31st + + function a() { + // Lowercase Ante meridiem and Post meridiem + return self.getHours() > 11? "pm" : "am"; + } + function A() { + // Uppercase Ante meridiem and Post meridiem + return self.getHours() > 11? "PM" : "AM"; + } + + function B(){ + // Swatch internet time. code simply grabbed from ppk, + // since I was feeling lazy: + // http://www.xs4all.nl/~ppk/js/beat.html + var off = (self.getTimezoneOffset() + 60)*60; + var theSeconds = (self.getHours() * 3600) + + (self.getMinutes() * 60) + + self.getSeconds() + off; + var beat = Math.floor(theSeconds/86.4); + if (beat > 1000) beat -= 1000; + if (beat < 0) beat += 1000; + if ((""+beat).length == 1) beat = "00"+beat; + if ((""+beat).length == 2) beat = "0"+beat; + return beat; + } + + function d() { + // Day of the month, 2 digits with leading zeros + return new String(self.getDate()).length == 1? + "0"+self.getDate() : self.getDate(); + } + function D() { + // A textual representation of a day, three letters + return daysShort[self.getDay()]; + } + function F() { + // A full textual representation of a month + return monthsLong[self.getMonth()]; + } + function g() { + // 12-hour format of an hour without leading zeros + return self.getHours() > 12? self.getHours()-12 : self.getHours(); + } + function G() { + // 24-hour format of an hour without leading zeros + return self.getHours(); + } + function h() { + // 12-hour format of an hour with leading zeros + if (self.getHours() > 12) { + var s = new String(self.getHours()-12); + return s.length == 1? + "0"+ (self.getHours()-12) : self.getHours()-12; + } else { + var s = new String(self.getHours()); + return s.length == 1? + "0"+self.getHours() : self.getHours(); + } + } + function H() { + // 24-hour format of an hour with leading zeros + return new String(self.getHours()).length == 1? + "0"+self.getHours() : self.getHours(); + } + function i() { + // Minutes with leading zeros + return new String(self.getMinutes()).length == 1? + "0"+self.getMinutes() : self.getMinutes(); + } + function j() { + // Day of the month without leading zeros + return self.getDate(); + } + function l() { + // A full textual representation of the day of the week + return daysLong[self.getDay()]; + } + function L() { + // leap year or not. 1 if leap year, 0 if not. + // the logic should match iso's 8601 standard. + var y_ = Y(); + if ( + (y_ % 4 == 0 && y_ % 100 != 0) || + (y_ % 4 == 0 && y_ % 100 == 0 && y_ % 400 == 0) + ) { + return 1; + } else { + return 0; + } + } + function m() { + // Numeric representation of a month, with leading zeros + return self.getMonth() < 9? + "0"+(self.getMonth()+1) : + self.getMonth()+1; + } + function M() { + // A short textual representation of a month, three letters + return monthsShort[self.getMonth()]; + } + function n() { + // Numeric representation of a month, without leading zeros + return self.getMonth()+1; + } + function O() { + // Difference to Greenwich time (GMT) in hours + var os = Math.abs(self.getTimezoneOffset()); + var h = ""+Math.floor(os/60); + var m = ""+(os%60); + h.length == 1? h = "0"+h:1; + m.length == 1? m = "0"+m:1; + return self.getTimezoneOffset() < 0 ? "+"+h+m : "-"+h+m; + } + function r() { + // RFC 822 formatted date + var r; // result + // Thu , 21 Dec 2000 + r = D() + ", " + j() + " " + M() + " " + Y() + + // 16 : 01 : 07 +0200 + " " + H() + ":" + i() + ":" + s() + " " + O(); + return r; + } + function S() { + // English ordinal suffix for the day of the month, 2 characters + return daysSuffix[self.getDate()-1]; + } + function s() { + // Seconds, with leading zeros + return new String(self.getSeconds()).length == 1? + "0"+self.getSeconds() : self.getSeconds(); + } + function t() { + + // thanks to Matt Bannon for some much needed code-fixes here! + var daysinmonths = [null,31,28,31,30,31,30,31,31,30,31,30,31]; + if (L()==1 && n()==2) return 29; // leap day + return daysinmonths[n()]; + } + function U() { + // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) + return Math.round(self.getTime()/1000); + } + function W() { + // Weeknumber, as per ISO specification: + // http://www.cl.cam.ac.uk/~mgk25/iso-time.html + + // if the day is three days before newyears eve, + // there's a chance it's "week 1" of next year. + // here we check for that. + var beforeNY = 364+L() - z(); + var afterNY = z(); + var weekday = w()!=0?w()-1:6; // makes sunday (0), into 6. + if (beforeNY <= 2 && weekday <= 2-beforeNY) { + return 1; + } + // similarly, if the day is within threedays of newyears + // there's a chance it belongs in the old year. + var ny = new Date("January 1 " + Y() + " 00:00:00"); + var nyDay = ny.getDay()!=0?ny.getDay()-1:6; + if ( + (afterNY <= 2) && + (nyDay >=4) && + (afterNY >= (6-nyDay)) + ) { + // Since I'm not sure we can just always return 53, + // i call the function here again, using the last day + // of the previous year, as the date, and then just + // return that week. + var prevNY = new Date("December 31 " + (Y()-1) + " 00:00:00"); + return prevNY.formatDate("W"); + } + + // week 1, is the week that has the first thursday in it. + // note that this value is not zero index. + if (nyDay <= 3) { + // first day of the year fell on a thursday, or earlier. + return 1 + Math.floor( ( z() + nyDay ) / 7 ); + } else { + // first day of the year fell on a friday, or later. + return 1 + Math.floor( ( z() - ( 7 - nyDay ) ) / 7 ); + } + } + function w() { + // Numeric representation of the day of the week + return self.getDay(); + } + + function Y() { + // A full numeric representation of a year, 4 digits + + // we first check, if getFullYear is supported. if it + // is, we just use that. ppks code is nice, but wont + // work with dates outside 1900-2038, or something like that + if (self.getFullYear) { + var newDate = new Date("January 1 2001 00:00:00 +0000"); + var x = newDate .getFullYear(); + if (x == 2001) { + // i trust the method now + return self.getFullYear(); + } + } + // else, do this: + // codes thanks to ppk: + // http://www.xs4all.nl/~ppk/js/introdate.html + var x = self.getYear(); + var y = x % 100; + y += (y < 38) ? 2000 : 1900; + return y; + } + function y() { + // A two-digit representation of a year + var y = Y()+""; + return y.substring(y.length-2,y.length); + } + function z() { + // The day of the year, zero indexed! 0 through 366 + var t = new Date("January 1 " + Y() + " 00:00:00"); + var diff = self.getTime() - t.getTime(); + return Math.floor(diff/1000/60/60/24); + } + + var self = this; + if (time) { + // save time + var prevTime = self.getTime(); + self.setTime(time); + } + + var ia = input.split(""); + var ij = 0; + while (ia[ij]) { + if (ia[ij] == "\\") { + // this is our way of allowing users to escape stuff + ia.splice(ij,1); + } else { + if (arrayExists(switches,ia[ij])) { + ia[ij] = eval(ia[ij] + "()"); + } + } + ij++; + } + // reset time, back to what it was + if (prevTime) { + self.setTime(prevTime); + } + return ia.join(""); +} + +var date = new Date("1/1/2007 1:11:11"); + +for (i = 0; i < 60000; ++i) { + var shortFormat = date.formatDate("Y-m-d"); + var longFormat = date.formatDate("l, F d, Y g:i:s A"); + date.setTime(date.getTime() + 84266956); +} + +// FIXME: Find a way to validate this test. +// https://bugs.webkit.org/show_bug.cgi?id=114849 diff --git a/PerformanceTests/LongSpider/date-format-xparb.js b/PerformanceTests/LongSpider/date-format-xparb.js new file mode 100644 index 0000000..b5d70ee --- /dev/null +++ b/PerformanceTests/LongSpider/date-format-xparb.js @@ -0,0 +1,420 @@ +/* + * Copyright (C) 2004 Baron Schwartz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, version 2.1. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + */ + +Date.parseFunctions = {count:0}; +Date.parseRegexes = []; +Date.formatFunctions = {count:0}; + +Date.prototype.dateFormat = function(format) { + if (Date.formatFunctions[format] == null) { + Date.createNewFormat(format); + } + var func = Date.formatFunctions[format]; + return this[func](); +} + +Date.createNewFormat = function(format) { + var funcName = "format" + Date.formatFunctions.count++; + Date.formatFunctions[format] = funcName; + var code = "Date.prototype." + funcName + " = function(){return "; + var special = false; + var ch = ''; + for (var i = 0; i < format.length; ++i) { + ch = format.charAt(i); + if (!special && ch == "\\") { + special = true; + } + else if (special) { + special = false; + code += "'" + String.escape(ch) + "' + "; + } + else { + code += Date.getFormatCode(ch); + } + } + eval(code.substring(0, code.length - 3) + ";}"); +} + +Date.getFormatCode = function(character) { + switch (character) { + case "d": + return "String.leftPad(this.getDate(), 2, '0') + "; + case "D": + return "Date.dayNames[this.getDay()].substring(0, 3) + "; + case "j": + return "this.getDate() + "; + case "l": + return "Date.dayNames[this.getDay()] + "; + case "S": + return "this.getSuffix() + "; + case "w": + return "this.getDay() + "; + case "z": + return "this.getDayOfYear() + "; + case "W": + return "this.getWeekOfYear() + "; + case "F": + return "Date.monthNames[this.getMonth()] + "; + case "m": + return "String.leftPad(this.getMonth() + 1, 2, '0') + "; + case "M": + return "Date.monthNames[this.getMonth()].substring(0, 3) + "; + case "n": + return "(this.getMonth() + 1) + "; + case "t": + return "this.getDaysInMonth() + "; + case "L": + return "(this.isLeapYear() ? 1 : 0) + "; + case "Y": + return "this.getFullYear() + "; + case "y": + return "('' + this.getFullYear()).substring(2, 4) + "; + case "a": + return "(this.getHours() < 12 ? 'am' : 'pm') + "; + case "A": + return "(this.getHours() < 12 ? 'AM' : 'PM') + "; + case "g": + return "((this.getHours() %12) ? this.getHours() % 12 : 12) + "; + case "G": + return "this.getHours() + "; + case "h": + return "String.leftPad((this.getHours() %12) ? this.getHours() % 12 : 12, 2, '0') + "; + case "H": + return "String.leftPad(this.getHours(), 2, '0') + "; + case "i": + return "String.leftPad(this.getMinutes(), 2, '0') + "; + case "s": + return "String.leftPad(this.getSeconds(), 2, '0') + "; + case "O": + return "this.getGMTOffset() + "; + case "T": + return "this.getTimezone() + "; + case "Z": + return "(this.getTimezoneOffset() * -60) + "; + default: + return "'" + String.escape(character) + "' + "; + } +} + +Date.parseDate = function(input, format) { + if (Date.parseFunctions[format] == null) { + Date.createParser(format); + } + var func = Date.parseFunctions[format]; + return Date[func](input); +} + +Date.createParser = function(format) { + var funcName = "parse" + Date.parseFunctions.count++; + var regexNum = Date.parseRegexes.length; + var currentGroup = 1; + Date.parseFunctions[format] = funcName; + + var code = "Date." + funcName + " = function(input){\n" + + "var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1;\n" + + "var d = new Date();\n" + + "y = d.getFullYear();\n" + + "m = d.getMonth();\n" + + "d = d.getDate();\n" + + "var results = input.match(Date.parseRegexes[" + regexNum + "]);\n" + + "if (results && results.length > 0) {" + var regex = ""; + + var special = false; + var ch = ''; + for (var i = 0; i < format.length; ++i) { + ch = format.charAt(i); + if (!special && ch == "\\") { + special = true; + } + else if (special) { + special = false; + regex += String.escape(ch); + } + else { + obj = Date.formatCodeToRegex(ch, currentGroup); + currentGroup += obj.g; + regex += obj.s; + if (obj.g && obj.c) { + code += obj.c; + } + } + } + + code += "if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n" + + "{return new Date(y, m, d, h, i, s);}\n" + + "else if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n" + + "{return new Date(y, m, d, h, i);}\n" + + "else if (y > 0 && m >= 0 && d > 0 && h >= 0)\n" + + "{return new Date(y, m, d, h);}\n" + + "else if (y > 0 && m >= 0 && d > 0)\n" + + "{return new Date(y, m, d);}\n" + + "else if (y > 0 && m >= 0)\n" + + "{return new Date(y, m);}\n" + + "else if (y > 0)\n" + + "{return new Date(y);}\n" + + "}return null;}"; + + Date.parseRegexes[regexNum] = new RegExp("^" + regex + "$"); + eval(code); +} + +Date.formatCodeToRegex = function(character, currentGroup) { + switch (character) { + case "D": + return {g:0, + c:null, + s:"(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)"}; + case "j": + case "d": + return {g:1, + c:"d = parseInt(results[" + currentGroup + "], 10);\n", + s:"(\\d{1,2})"}; + case "l": + return {g:0, + c:null, + s:"(?:" + Date.dayNames.join("|") + ")"}; + case "S": + return {g:0, + c:null, + s:"(?:st|nd|rd|th)"}; + case "w": + return {g:0, + c:null, + s:"\\d"}; + case "z": + return {g:0, + c:null, + s:"(?:\\d{1,3})"}; + case "W": + return {g:0, + c:null, + s:"(?:\\d{2})"}; + case "F": + return {g:1, + c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "].substring(0, 3)], 10);\n", + s:"(" + Date.monthNames.join("|") + ")"}; + case "M": + return {g:1, + c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "]], 10);\n", + s:"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"}; + case "n": + case "m": + return {g:1, + c:"m = parseInt(results[" + currentGroup + "], 10) - 1;\n", + s:"(\\d{1,2})"}; + case "t": + return {g:0, + c:null, + s:"\\d{1,2}"}; + case "L": + return {g:0, + c:null, + s:"(?:1|0)"}; + case "Y": + return {g:1, + c:"y = parseInt(results[" + currentGroup + "], 10);\n", + s:"(\\d{4})"}; + case "y": + return {g:1, + c:"var ty = parseInt(results[" + currentGroup + "], 10);\n" + + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n", + s:"(\\d{1,2})"}; + case "a": + return {g:1, + c:"if (results[" + currentGroup + "] == 'am') {\n" + + "if (h == 12) { h = 0; }\n" + + "} else { if (h < 12) { h += 12; }}", + s:"(am|pm)"}; + case "A": + return {g:1, + c:"if (results[" + currentGroup + "] == 'AM') {\n" + + "if (h == 12) { h = 0; }\n" + + "} else { if (h < 12) { h += 12; }}", + s:"(AM|PM)"}; + case "g": + case "G": + case "h": + case "H": + return {g:1, + c:"h = parseInt(results[" + currentGroup + "], 10);\n", + s:"(\\d{1,2})"}; + case "i": + return {g:1, + c:"i = parseInt(results[" + currentGroup + "], 10);\n", + s:"(\\d{2})"}; + case "s": + return {g:1, + c:"s = parseInt(results[" + currentGroup + "], 10);\n", + s:"(\\d{2})"}; + case "O": + return {g:0, + c:null, + s:"[+-]\\d{4}"}; + case "T": + return {g:0, + c:null, + s:"[A-Z]{3}"}; + case "Z": + return {g:0, + c:null, + s:"[+-]\\d{1,5}"}; + default: + return {g:0, + c:null, + s:String.escape(character)}; + } +} + +Date.prototype.getTimezone = function() { + return this.toString().replace( + /^.*? ([A-Z]{3}) [0-9]{4}.*$/, "$1").replace( + /^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/, "$1$2$3"); +} + +Date.prototype.getGMTOffset = function() { + return (this.getTimezoneOffset() > 0 ? "-" : "+") + + String.leftPad(Math.floor(this.getTimezoneOffset() / 60), 2, "0") + + String.leftPad(this.getTimezoneOffset() % 60, 2, "0"); +} + +Date.prototype.getDayOfYear = function() { + var num = 0; + Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28; + for (var i = 0; i < this.getMonth(); ++i) { + num += Date.daysInMonth[i]; + } + return num + this.getDate() - 1; +} + +Date.prototype.getWeekOfYear = function() { + // Skip to Thursday of this week + var now = this.getDayOfYear() + (4 - this.getDay()); + // Find the first Thursday of the year + var jan1 = new Date(this.getFullYear(), 0, 1); + var then = (7 - jan1.getDay() + 4); + document.write(then); + return String.leftPad(((now - then) / 7) + 1, 2, "0"); +} + +Date.prototype.isLeapYear = function() { + var year = this.getFullYear(); + return ((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year))); +} + +Date.prototype.getFirstDayOfMonth = function() { + var day = (this.getDay() - (this.getDate() - 1)) % 7; + return (day < 0) ? (day + 7) : day; +} + +Date.prototype.getLastDayOfMonth = function() { + var day = (this.getDay() + (Date.daysInMonth[this.getMonth()] - this.getDate())) % 7; + return (day < 0) ? (day + 7) : day; +} + +Date.prototype.getDaysInMonth = function() { + Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28; + return Date.daysInMonth[this.getMonth()]; +} + +Date.prototype.getSuffix = function() { + switch (this.getDate()) { + case 1: + case 21: + case 31: + return "st"; + case 2: + case 22: + return "nd"; + case 3: + case 23: + return "rd"; + default: + return "th"; + } +} + +String.escape = function(string) { + return string.replace(/('|\\)/g, "\\$1"); +} + +String.leftPad = function (val, size, ch) { + var result = new String(val); + if (ch == null) { + ch = " "; + } + while (result.length < size) { + result = ch + result; + } + return result; +} + +Date.daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31]; +Date.monthNames = + ["January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December"]; +Date.dayNames = + ["Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday"]; +Date.y2kYear = 50; +Date.monthNumbers = { + Jan:0, + Feb:1, + Mar:2, + Apr:3, + May:4, + Jun:5, + Jul:6, + Aug:7, + Sep:8, + Oct:9, + Nov:10, + Dec:11}; +Date.patterns = { + ISO8601LongPattern:"Y-m-d H:i:s", + ISO8601ShortPattern:"Y-m-d", + ShortDatePattern: "n/j/Y", + LongDatePattern: "l, F d, Y", + FullDateTimePattern: "l, F d, Y g:i:s A", + MonthDayPattern: "F d", + ShortTimePattern: "g:i A", + LongTimePattern: "g:i:s A", + SortableDateTimePattern: "Y-m-d\\TH:i:s", + UniversalSortableDateTimePattern: "Y-m-d H:i:sO", + YearMonthPattern: "F, Y"}; + +var date = new Date("1/1/2007 1:11:11"); + +for (i = 0; i < 900000; ++i) { + var shortFormat = date.dateFormat("Y-m-d"); + var longFormat = date.dateFormat("l, F d, Y g:i:s A"); + date.setTime(date.getTime() + 84266956); +} + +// FIXME: Find a way to validate this test. +// https://bugs.webkit.org/show_bug.cgi?id=114849 diff --git a/PerformanceTests/LongSpider/math-cordic.js b/PerformanceTests/LongSpider/math-cordic.js new file mode 100644 index 0000000..790480e --- /dev/null +++ b/PerformanceTests/LongSpider/math-cordic.js @@ -0,0 +1,106 @@ +/* + * Copyright (C) Rich Moore. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////. Start CORDIC + +var AG_CONST = 0.6072529350; + +function FIXED(X) +{ + return X * 65536.0; +} + +function FLOAT(X) +{ + return X / 65536.0; +} + +function DEG2RAD(X) +{ + return 0.017453 * (X); +} + +var Angles = [ + FIXED(45.0), FIXED(26.565), FIXED(14.0362), FIXED(7.12502), + FIXED(3.57633), FIXED(1.78991), FIXED(0.895174), FIXED(0.447614), + FIXED(0.223811), FIXED(0.111906), FIXED(0.055953), + FIXED(0.027977) + ]; + +var Target = 28.027; + +function cordicsincos(Target) { + var X; + var Y; + var TargetAngle; + var CurrAngle; + var Step; + + X = FIXED(AG_CONST); /* AG_CONST * cos(0) */ + Y = 0; /* AG_CONST * sin(0) */ + + TargetAngle = FIXED(Target); + CurrAngle = 0; + for (Step = 0; Step < 12; Step++) { + var NewX; + if (TargetAngle > CurrAngle) { + NewX = X - (Y >> Step); + Y = (X >> Step) + Y; + X = NewX; + CurrAngle += Angles[Step]; + } else { + NewX = X + (Y >> Step); + Y = -(X >> Step) + Y; + X = NewX; + CurrAngle -= Angles[Step]; + } + } + + return FLOAT(X) * FLOAT(Y); +} + +///// End CORDIC + +var total = 0; + +function cordic( runs ) { + var start = new Date(); + + for ( var i = 0 ; i < runs ; i++ ) { + total += cordicsincos(Target); + } + + var end = new Date(); + + return end.getTime() - start.getTime(); +} + +cordic(13000000); + +var expected = 5388536.644120298; + +if (total != expected) + throw "ERROR: bad result: expected " + expected + " but got " + total; + diff --git a/PerformanceTests/LongSpider/math-partial-sums.js b/PerformanceTests/LongSpider/math-partial-sums.js new file mode 100644 index 0000000..4ece357 --- /dev/null +++ b/PerformanceTests/LongSpider/math-partial-sums.js @@ -0,0 +1,45 @@ +// The Computer Language Shootout +// http://shootout.alioth.debian.org/ +// contributed by Isaac Gouy + +function partial(n){ + var a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 = 0.0; + var twothirds = 2.0/3.0; + var alt = -1.0; + var k2 = k3 = sk = ck = 0.0; + + for (var k = 1; k <= n; k++){ + k2 = k*k; + k3 = k2*k; + sk = Math.sin(k); + ck = Math.cos(k); + alt = -alt; + + a1 += Math.pow(twothirds,k-1); + a2 += Math.pow(k,-0.5); + a3 += 1.0/(k*(k+1.0)); + a4 += 1.0/(k3 * sk*sk); + a5 += 1.0/(k3 * ck*ck); + a6 += 1.0/k; + a7 += 1.0/k2; + a8 += alt/k; + a9 += alt/(2*k -1); + } + + // NOTE: We don't try to validate anything from pow(), sin() or cos() because those aren't + // well-specified in ECMAScript. + return a6 + a7 + a8 + a9; +} + +var total = 0; + +for (var i = 1024; i <= 2097152; i *= 2) { + total += partial(i); +} + +var expected = 173.3312765300306; + +if (total != expected) { + throw "ERROR: bad result: expected " + expected + " but got " + total; +} + diff --git a/PerformanceTests/LongSpider/math-spectral-norm.js b/PerformanceTests/LongSpider/math-spectral-norm.js new file mode 100644 index 0000000..b79cf01 --- /dev/null +++ b/PerformanceTests/LongSpider/math-spectral-norm.js @@ -0,0 +1,59 @@ +// The Great Computer Language Shootout +// http://shootout.alioth.debian.org/ +// +// contributed by Ian Osgood + +function A(i,j) { + return 1/((i+j)*(i+j+1)/2+i+1); +} + +function Au(u,v) { + for (var i=0; i (original author) + * Samuel Sieb + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// From: http://lxr.mozilla.org/mozilla/source/extensions/xml-rpc/src/nsXmlRpcClient.js#956 + +/* Convert data (an array of integers) to a Base64 string. */ +var toBase64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; +var base64Pad = '='; + +function toBase64(data) { + var result = ''; + var length = data.length; + var i; + // Convert every three bytes to 4 ascii characters. + for (i = 0; i < (length - 2); i += 3) { + result += toBase64Table[data.charCodeAt(i) >> 2]; + result += toBase64Table[((data.charCodeAt(i) & 0x03) << 4) + (data.charCodeAt(i+1) >> 4)]; + result += toBase64Table[((data.charCodeAt(i+1) & 0x0f) << 2) + (data.charCodeAt(i+2) >> 6)]; + result += toBase64Table[data.charCodeAt(i+2) & 0x3f]; + } + + // Convert the remaining 1 or 2 bytes, pad out to 4 characters. + if (length%3) { + i = length - (length%3); + result += toBase64Table[data.charCodeAt(i) >> 2]; + if ((length%3) == 2) { + result += toBase64Table[((data.charCodeAt(i) & 0x03) << 4) + (data.charCodeAt(i+1) >> 4)]; + result += toBase64Table[(data.charCodeAt(i+1) & 0x0f) << 2]; + result += base64Pad; + } else { + result += toBase64Table[(data.charCodeAt(i) & 0x03) << 4]; + result += base64Pad + base64Pad; + } + } + + return result; +} + +/* Convert Base64 data to a string */ +var toBinaryTable = [ + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, + 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, + 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, + -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, + 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 +]; + +function base64ToString(data) { + var result = ''; + var leftbits = 0; // number of bits decoded, but yet to be appended + var leftdata = 0; // bits decoded, but yet to be appended + + // Convert one by one. + for (var i = 0; i < data.length; i++) { + var c = toBinaryTable[data.charCodeAt(i) & 0x7f]; + var padding = (data.charCodeAt(i) == base64Pad.charCodeAt(0)); + // Skip illegal characters and whitespace + if (c == -1) continue; + + // Collect data into leftdata, update bitcount + leftdata = (leftdata << 6) | c; + leftbits += 6; + + // If we have 8 or more bits, append 8 bits to the result + if (leftbits >= 8) { + leftbits -= 8; + // Append if not padding. + if (!padding) + result += String.fromCharCode((leftdata >> leftbits) & 0xff); + leftdata &= (1 << leftbits) - 1; + } + } + + // If there are any bits left, the base64 string was corrupted + if (leftbits) + throw Components.Exception('Corrupted base64 string'); + + return result; +} + +var str = ""; + +for ( var i = 0; i < 8192; i++ ) + str += String.fromCharCode( (25 * Math.random()) + 97 ); + +for ( var i = 8192; i <= 2097152; i *= 2 ) { + + var base64; + + base64 = toBase64(str); + var encoded = base64ToString(base64); + if (encoded != str) + throw "ERROR: bad result: expected " + str + " but got " + encoded; + + // Double the string + str += str; +} + +toBinaryTable = null; diff --git a/PerformanceTests/LongSpider/string-fasta.js b/PerformanceTests/LongSpider/string-fasta.js new file mode 100644 index 0000000..d217126 --- /dev/null +++ b/PerformanceTests/LongSpider/string-fasta.js @@ -0,0 +1,90 @@ +// The Great Computer Language Shootout +// http://shootout.alioth.debian.org +// +// Contributed by Ian Osgood + +var last = 42, A = 3877, C = 29573, M = 139968; + +function rand(max) { + last = (last * A + C) % M; + return max * last / M; +} + +var ALU = + "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG" + + "GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA" + + "CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT" + + "ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA" + + "GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG" + + "AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC" + + "AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA"; + +var IUB = { + a:0.27, c:0.12, g:0.12, t:0.27, + B:0.02, D:0.02, H:0.02, K:0.02, + M:0.02, N:0.02, R:0.02, S:0.02, + V:0.02, W:0.02, Y:0.02 +} + +var HomoSap = { + a: 0.3029549426680, + c: 0.1979883004921, + g: 0.1975473066391, + t: 0.3015094502008 +} + +function makeCumulative(table) { + var last = null; + for (var c in table) { + if (last) table[c] += table[last]; + last = c; + } +} + +function fastaRepeat(n, seq) { + var seqi = 0, lenOut = 60; + while (n>0) { + if (n0) { + if (n= 0x7f) { + validates = false; + break; + } + } + + if (!validates) + continue; + + var url = "http://example.com/tag/" + tag.replace(" ", "").toLowerCase(); + var popularity = tagInfo[i].popularity; + var color = 'rgb(' + Math.floor(255 * (popularity - 12) / 20) + ', 0, 255)'; + output += ' ' + tag + ' \n'; + } + + output += ''; + output.replace(" ", " "); + + return output; + } + + var tagcloud = makeTagCloud(tagInfo); + + var expectedMinLength = 315000; + + if (tagcloud.length < expectedMinLength) + throw "ERROR: bad result: expected length at least " + expectedMinLength + " but got " + tagcloud.length; + + tagInfo = null; +} + -- 1.8.3.1