diff --git a/__tests__/benchmark.data.js b/__tests__/benchmark.data.js new file mode 100644 index 0000000000000000000000000000000000000000..1426d5216d9480e1d7db3404c1ebe4c144697dbb --- /dev/null +++ b/__tests__/benchmark.data.js @@ -0,0 +1,319 @@ +export const handshake = { + uid: "tiger", + channel: "tw-ml", + message: { + uuid: "42c4566d-0cfe-4c00-a645-254b7887e477", + message: Uint8Array.of(162, 109, 108), + slice: 0, + length: 1, + compressed: false, + }, +} + +export const dotDraw = [[209, 88, 5.000000000000001, "#0000ff"]] +export const dotErase = [[0, [[0, 0]]]] + +export const pathDraw = [ + [229, 147, 5.000000000000001, "#0000ff"], + [239, 149, 5.000000000000001, "#0000ff"], + [265, 154, 5.000000000000001, "#0000ff"], + [329, 158, 5.000000000000001, "#0000ff"], + [428, 168, 5.000000000000001, "#0000ff"], + [559, 172, 5.000000000000001, "#0000ff"], + [689, 176, 5.000000000000001, "#0000ff"], + [789, 176, 5.000000000000001, "#0000ff"], + [871, 178, 5.000000000000001, "#0000ff"], + [915, 179, 5.000000000000001, "#0000ff"], + [937, 179, 5.000000000000001, "#0000ff"], + [942, 179, 5.000000000000001, "#0000ff"], +] +export const pathErase = [ + [0, [[0, 0.030367582231477598]]], + [0, [[0, 0.21377102974828613]]], + [0, [[0, 0.2537463508623564]]], + [0, [[0, 0.34615384615384587]]], + [0, [[0, 0.4383613354449363]]], + [0, [[0, 0.5303675822314777]]], + [0, [[0, 0.6221712759429692]]], + [0, [[0, 0.7137710297482863]]], + [0, [[0, 0.8051653782004998]]], + [0, [[0, 0.9383613354449363]]], + [0, [[0, 1]]], + [1, [[0, 0.011716311379342382]]], + [1, [[0, 0.11776520948773353]]], + [1, [[0, 0.24006055181058228]]], + [1, [[0, 0.3107159148890084]]], + [1, [[0, 0.3810746303975673]]], + [1, [[0, 0.4329788671985464]]], + [1, [[0, 0.46835801309405006]]], + [1, [[0, 0.5036636541863274]]], + [1, [[0, 0.5740522382479196]]], + [1, [[0, 0.6441399664465288]]], + [1, [[0, 0.731854882371686]]], + [1, [[0, 0.8021237085400632]]], + [1, [[0, 0.8371448744989799]]], + [1, [[0, 0.88955025220044]]], + [1, [[0, 0.9599984343180302]]], + [1, [[0, 1]]], + [2, [[0, 0.028177027652500065]]], + [2, [[0, 0.03543420592413073]]], + [2, [[0, 0.06582991759489924]]], + [2, [[0, 0.10275381734879]]], + [2, [[0, 0.11799692411252251]]], + [2, [[0, 0.13323648198760243]]], + [2, [[0, 0.16370490408198182]]], + [2, [[0, 0.2154080009026301]]], + [2, [[0, 0.24595364724469834]]], + [2, [[0, 0.27648544742767633]]], + [2, [[0, 0.31247481764398494]]], + [2, [[0, 0.3478072470007028]]], + [2, [[0, 0.3785134252130592]]], + [2, [[0, 0.3938616312677431]]], + [2, [[0, 0.42869266182685783]]], + [2, [[0, 0.44408271983476183]]], + [2, [[0, 0.4594695941376009]]], + [2, [[0, 0.4902337694168022]]], + [2, [[0, 0.505611059005356]]], + [2, [[0, 0.5246181146997148]]], + [2, [[0, 0.5400397300348875]]], + [2, [[0, 0.6047746406708809]]], + [2, [[0, 0.6202304708442001]]], + [2, [[0, 0.6356832087546725]]], + [2, [[0, 0.6535687967630837]]], + [2, [[0, 0.7000469301249926]]], + [2, [[0, 0.7155335204468358]]], + [2, [[0, 0.7484433368793898]]], + [2, [[0, 0.8415551828545537]]], + [2, [[0, 0.8896745156013701]]], + [2, [[0, 0.9207665061568425]]], + [2, [[0, 0.9518463520584276]]], + [2, [[0, 0.9840324922550672]]], + [2, [[0, 1]]], + [3, [[0, 0.01983903263791853]]], + [3, [[0, 0.029876622283678104]]], + [3, [[0, 0.03990912701215377]]], + [3, [[0, 0.0806437862168895]]], + [3, [[0, 0.09070123866218649]]], + [3, [[0, 0.10101007524615979]]], + [3, [[0, 0.11110799523965204]]], + [3, [[0, 0.12120077057322706]]], + [3, [[0, 0.13128840847448436]]], + [3, [[0, 0.15144829885129574]]], + [3, [[0, 0.16152056375068494]]], + [3, [[0, 0.1818098260284825]]], + [3, [[0, 0.20202009896967427]]], + [3, [[0, 0.21211750416023725]]], + [3, [[0, 0.2727084630640253]]], + [3, [[0, 0.29292802997685985]]], + [3, [[0, 0.3030300711783685]]], + [3, [[0, 0.33330532017010783]]], + [3, [[0, 0.3636029076253441]]], + [3, [[0, 0.37371993253130364]]], + [3, [[0, 0.3838317824361028]]], + [3, [[0, 0.40403999188002426]]], + [3, [[0, 0.41413636769223433]]], + [3, [[0, 0.42422760105585006]]], + [3, [[0, 0.43431369907567324]]], + [3, [[0, 0.4443662699271226]]], + [3, [[0, 0.4544931529993546]]], + [3, [[0, 0.46461484324950236]]], + [3, [[0, 0.4747313502489194]]], + [3, [[0, 0.5050498610823838]]], + [3, [[0, 0.5151457223183467]]], + [3, [[0, 0.5353220266951074]]], + [3, [[0, 0.5454024835564785]]], + [3, [[0, 0.5858535321955943]]], + [3, [[0, 0.5959591836309699]]], + [3, [[0, 0.616155025527601]]], + [3, [[0, 0.6463920624411829]]], + [3, [[0, 0.6666385590106888]]], + [3, [[0, 0.6767540304709369]]], + [3, [[0, 0.6969694650467834]]], + [3, [[0, 0.7474179601261248]]], + [3, [[0, 0.7675614683096057]]], + [3, [[0, 0.7776255556078067]]], + [3, [[0, 0.8282626561208872]]], + [3, [[0, 0.8484256216002729]]], + [3, [[0, 0.8584994213492495]]], + [3, [[0, 0.8685681068775302]]], + [3, [[0, 0.9087918074364576]]], + [3, [[0, 0.9188349938933553]]], + [3, [[0, 0.9288730921857218]]], + [3, [[0, 0.9889949697600137]]], + [3, [[0, 0.99974858647489]]], + [3, [[0, 1]]], + [4, [[0, 0.015052512188419602]]], + [4, [[0, 0.03029426962088413]]], + [4, [[0, 0.06839243749770468]]], + [4, [[0, 0.0836292133608997]]], + [4, [[0, 0.0912470672285808]]], + [4, [[0, 0.09886456497394153]]], + [4, [[0, 0.13734696870310906]]], + [4, [[0, 0.14497397901135212]]], + [4, [[0, 0.16022693354357556]]], + [4, [[0, 0.16785287776755597]]], + [4, [[0, 0.2061009857691912]]], + [4, [[0, 0.2213715432205954]]], + [4, [[0, 0.2290062878232259]]], + [4, [[0, 0.23664067642184725]]], + [4, [[0, 0.31287013784360607]]], + [4, [[0, 0.33579551026422]]], + [4, [[0, 0.3434365859114192]]], + [4, [[0, 0.37399731542592607]]], + [4, [[0, 0.3892755376794567]]], + [4, [[0, 0.3969141134976991]]], + [4, [[0, 0.41219019494203474]]], + [4, [[0, 0.47328026274975304]]], + [4, [[0, 0.48854921795242295]]], + [4, [[0, 0.5267153779648435]]], + [4, [[0, 0.5343475426943275]]], + [4, [[0, 0.5419793517647892]]], + [4, [[0, 0.5496108052135158]]], + [4, [[0, 0.5801330634496403]]], + [4, [[0, 0.5877627392618375]]], + [4, [[0, 0.5953920596237392]]], + [4, [[0, 0.610649634073643]]], + [4, [[0, 0.6487873509046499]]], + [4, [[0, 0.6564138281707615]]], + [4, [[0, 0.6640399500759696]]], + [4, [[0, 0.7174128527857359]]], + [4, [[0, 0.7326590547531385]]], + [4, [[0, 0.7402816225030254]]], + [4, [[0, 0.7555256913985305]]], + [4, [[0, 0.8469602239274668]]], + [4, [[0, 0.8621943289183245]]], + [4, [[0, 0.8698108469953234]]], + [4, [[0, 0.8774270087010998]]], + [4, [[0, 0.9078880903271799]]], + [4, [[0, 0.9155024690411608]]], + [4, [[0, 0.9231164909119645]]], + [4, [[0, 0.9307301558520772]]], + [4, [[0, 0.9769418956440951]]], + [4, [[0, 0.9845647300195252]]], + [4, [[0, 0.992187208890867]]], + [4, [[0, 0.9998093322301707]]], + [4, [[0, 1]]], + [5, [[0, 0.03820574873127833]]], + [5, [[0, 0.045884233047770166]]], + [5, [[0, 0.061240109456200745]]], + [5, [[0, 0.1226490440345489]]], + [5, [[0, 0.13032352057732857]]], + [5, [[0, 0.14567137935938093]]], + [5, [[0, 0.15334476144043718]]], + [5, [[0, 0.19170619534531316]]], + [5, [[0, 0.19937738618962128]]], + [5, [[0, 0.2070482114971963]]], + [5, [[0, 0.2453968513383652]]], + [5, [[0, 0.26073374476033434]]], + [5, [[0, 0.26840164189649224]]], + [5, [[0, 0.3067356268350702]]], + [5, [[0, 0.322066651341349]]], + [5, [[0, 0.32973161244332394]]], + [5, [[0, 0.34506043162274563]]], + [5, [[0, 0.39869970096661816]]], + [5, [[0, 0.4063609788597506]]], + [5, [[0, 0.41402188753199426]]], + [5, [[0, 0.4676378950251564]]], + [5, [[0, 0.47529584340574377]]], + [5, [[0, 0.5518548940788806]]], + [5, [[0, 0.5595087511478618]]], + [5, [[0, 0.56716223496407]]], + [5, [[0, 0.5824680819078778]]], + [5, [[0, 0.6686904305673842]]], + [5, [[0, 0.6917061953453132]]], + [5, [[0, 0.7070482114971963]]], + [5, [[0, 0.7766873397479431]]], + [5, [[0, 0.7923021861323849]]], + [5, [[0, 0.7999923098661218]]], + [5, [[0, 0.8076820697480561]]], + [5, [[0, 0.8614794103478556]]], + [5, [[0, 0.8768764254973112]]], + [5, [[0, 0.8845743850827851]]], + [5, [[0, 0.8922719794659787]]], + [5, [[0, 0.9458689803376649]]], + [5, [[0, 0.9612817605421127]]], + [5, [[0, 0.9689875986837584]]], + [5, [[0, 1]]], + [6, [[0, 0.029749843554381775]]], + [6, [[0, 0.059749843554381774]]], + [6, [[0, 0.06974984355438178]]], + [6, [[0, 0.13974984355438178]]], + [6, [[0, 0.14974984355438178]]], + [6, [[0, 0.15974984355438177]]], + [6, [[0, 0.16974984355438177]]], + [6, [[0, 0.17974984355438178]]], + [6, [[0, 0.21974984355438176]]], + [6, [[0, 0.22974984355438177]]], + [6, [[0, 0.23974984355438178]]], + [6, [[0, 0.2497498435543818]]], + [6, [[0, 0.3197498435543818]]], + [6, [[0, 0.3397498435543818]]], + [6, [[0, 0.3497498435543818]]], + [6, [[0, 0.35974984355438183]]], + [6, [[0, 0.468997487421324]]], + [6, [[0, 0.48899748742132404]]], + [6, [[0, 0.49899748742132405]]], + [6, [[0, 0.518997487421324]]], + [6, [[0, 0.6277371993328519]]], + [6, [[0, 0.6377371993328519]]], + [6, [[0, 0.6477371993328519]]], + [6, [[0, 0.6677371993328519]]], + [6, [[0, 0.7777371993328519]]], + [6, [[0, 0.7877371993328519]]], + [6, [[0, 0.8077371993328519]]], + [6, [[0, 0.9377371993328519]]], + [6, [[0, 0.957737199332852]]], + [6, [[0, 0.977737199332852]]], + [6, [[0, 1]]], + [7, [[0, 0.08434122461529223]]], + [7, [[0, 0.09736319249220814]]], + [7, [[0, 0.12177670236609432]]], + [7, [[0, 0.13398291047706393]]], + [7, [[0, 0.2560176149231152]]], + [7, [[0, 0.26820494288749264]]], + [7, [[0, 0.2803919084377965]]], + [7, [[0, 0.30476475227840155]]], + [7, [[0, 0.42434250381943905]]], + [7, [[0, 0.4364947880419225]]], + [7, [[0, 0.44864670195280104]]], + [7, [[0, 0.4607982453870106]]], + [7, [[0, 0.5822932659066377]]], + [7, [[0, 0.5944407226857343]]], + [7, [[0, 0.6065878068658583]]], + [7, [[0, 0.7298557216513387]]], + [7, [[0, 0.7420139098657976]]], + [7, [[0, 0.7541717301678039]]], + [7, [[0, 0.7663291824206042]]], + [7, [[0, 0.8284299052782537]]], + [7, [[0, 0.8406001691299525]]], + [7, [[0, 0.8649396036740605]]], + [7, [[0, 0.9753340606845997]]], + [7, [[0, 0.9875148632580261]]], + [7, [[0, 0.9996953030971739]]], + [7, [[0, 1]]], + [8, [[0, 0.022133273001338587]]], + [8, [[0, 0.20418547065439502]]], + [8, [[0, 0.22693303640624127]]], + [8, [[0, 0.24968001232099726]]], + [8, [[0, 0.272426398521291]]], + [8, [[0, 0.47595107564942674]]], + [8, [[0, 0.5214835194176608]]], + [8, [[0, 0.5442488489860375]]], + [8, [[0, 0.5670135839399206]]], + [8, [[0, 0.5897777244732638]]], + [8, [[0, 0.749110080215568]]], + [8, [[0, 0.7718694720767475]]], + [8, [[0, 0.7946282711542776]]], + [8, [[0, 0.8173864776180217]]], + [8, [[0, 1]]], + [9, [[0, 0.04431747070173535]]], + [9, [[0, 0.0897720161562808]]], + [9, [[0, 0.18068110706537172]]], + [9, [[0, 0.4988629252471899]]], + [9, [[0, 0.5897720161562808]]], + [9, [[0, 0.6352265616108262]]], + [9, [[0, 0.7261356525199172]]], + [9, [[0, 1]]], + [10, [[0, 1]]], + [11, [[0, 1]]], +] diff --git a/__tests__/benchmark.test.js b/__tests__/benchmark.test.js index 42bea5570edd4547b66982748b3aa949f316f108..20834ea7a91a97607933a5749bdb14d3b491a977 100644 --- a/__tests__/benchmark.test.js +++ b/__tests__/benchmark.test.js @@ -16,33 +16,33 @@ import MockConnection, { eventListeners, } from "../src/connection/MockConnection.js" +import { + handshake, + dotDraw, + dotErase, + pathDraw, + pathErase, +} from "./benchmark.data.js" + function printBenchmark(title, iterations, results) { - process.stdout.write(`\n ${title} (${iterations} its):\n`) + process.stdout.write(`\n ${title} (${iterations} iterations):\n`) for (const title in results) { + const { time, packets, size } = results[title] + process.stdout.write( chalk` {yellow ⧗} {dim ${title}:} {yellow.inverse ${( - results[title] / + time / (1e6 * iterations) - ).toFixed(3)}ms / it}\n`, + ).toFixed( + 3, + )}ms / it} {magenta.inverse ${size}B} {dim in ${packets} packet(s)}\n`, ) } process.stdout.write(`\n`) } -const handshake = { - uid: "tiger", - channel: "tw-ml", - message: { - uuid: "42c4566d-0cfe-4c00-a645-254b7887e477", - message: Uint8Array.of(162, 109, 108), - slice: 0, - length: 1, - compressed: false, - }, -} - let room = null describe("drawing app mesh", () => { @@ -76,9 +76,7 @@ describe("drawing app mesh", () => { resolve() } - dotID = room.addPath([209, 88, 5.000000000000001, "#0000ff"]) - - room.extendErasureIntervals(dotID, 0, 0, 0) + dotID = room.addPath(dotDraw[0]) }).then( () => new Promise((resolve) => { @@ -88,7 +86,7 @@ describe("drawing app mesh", () => { resolve() } - room.extendErasureIntervals(dotID, 0, [[0, 0]]) + room.extendErasureIntervals(dotID, dotErase[0][0], dotErase[0][1]) }), ) }) @@ -102,11 +100,16 @@ describe("drawing app mesh", () => { let prevTime let broadcasts = 0 + let addTime = 0 + let addPackets = 0 + let addSize = 0 let eraseTime = 0 + let erasePackets = 0 + let eraseSize = 0 return new Promise((resolve) => { - broadcastListener.callback = () => { + broadcastListener.callback = (channel, message) => { const currTime = process.hrtime() broadcasts += 1 @@ -114,23 +117,33 @@ describe("drawing app mesh", () => { if (broadcasts <= ITERATIONS) { addTime += (currTime[0] - prevTime[0]) * 1e9 + (currTime[1] - prevTime[1]) + addPackets += 1 + addSize += message.message.length } else { eraseTime += (currTime[0] - prevTime[0]) * 1e9 + (currTime[1] - prevTime[1]) + erasePackets += 1 + eraseSize += message.message.length } prevTime = process.hrtime() if (broadcasts < ITERATIONS) { - dotIDs.push(room.addPath([209, 88, 5.000000000000001, "#0000ff"])) + dotIDs.push(room.addPath(dotDraw[0])) } else if (broadcasts < ITERATIONS * 2) { - room.extendErasureIntervals(dotIDs[broadcasts - ITERATIONS], 0, [ - [0, 0], - ]) + room.extendErasureIntervals( + dotIDs[broadcasts - ITERATIONS], + dotErase[0][0], + dotErase[0][1], + ) } else { printBenchmark("single draw and erase [sequential]", ITERATIONS, { - addPath: addTime, - extendErasureIntervals: eraseTime, + addPath: { time: addTime, packets: addPackets, size: addSize }, + extendErasureIntervals: { + time: eraseTime, + packets: erasePackets, + size: eraseSize, + }, }) resolve() @@ -139,7 +152,7 @@ describe("drawing app mesh", () => { prevTime = process.hrtime() - dotIDs.push(room.addPath([209, 88, 5.000000000000001, "#0000ff"])) + dotIDs.push(room.addPath(dotDraw[0])) }) }) @@ -152,40 +165,52 @@ describe("drawing app mesh", () => { let prevTime let addTime + let addPackets = 0 + let addSize = 0 let eraseTime + let erasePackets = 0 + let eraseSize = 0 let timeout return new Promise((resolve) => { - broadcastListener.callback = () => { + broadcastListener.callback = (channel, message) => { const currTime = process.hrtime() addTime = (currTime[0] - prevTime[0]) * 1e9 + (currTime[1] - prevTime[1]) + addPackets += 1 + addSize += message.message.length clearTimeout(timeout) - setTimeout(() => resolve(), 1000) + timeout = setTimeout(() => resolve(), 1000) } prevTime = process.hrtime() for (let i = 0; i < ITERATIONS; i++) { - dotIDs.push(room.addPath([209, 88, 5.000000000000001, "#0000ff"])) + dotIDs.push(room.addPath(dotDraw[0])) } }).then( () => new Promise((resolve) => { - broadcastListener.callback = () => { + broadcastListener.callback = (channel, message) => { const currTime = process.hrtime() eraseTime = (currTime[0] - prevTime[0]) * 1e9 + (currTime[1] - prevTime[1]) + erasePackets += 1 + eraseSize += message.message.length clearTimeout(timeout) - setTimeout(() => { + timeout = setTimeout(() => { printBenchmark("single draw and erase [parallel]", ITERATIONS, { - addPath: addTime, - extendErasureIntervals: eraseTime, + addPath: { time: addTime, packets: addPackets, size: addSize }, + extendErasureIntervals: { + time: eraseTime, + packets: erasePackets, + size: eraseSize, + }, }) resolve() @@ -195,7 +220,51 @@ describe("drawing app mesh", () => { prevTime = process.hrtime() for (let i = 0; i < ITERATIONS; i++) { - room.extendErasureIntervals(dotIDs[i], 0, [[0, 0]]) + room.extendErasureIntervals( + dotIDs[i], + dotErase[0][0], + dotErase[0][1], + ) + } + }), + ) + }) + + it("communicates a path draw and erase update", () => { + let pathID + + let timeout + + return new Promise((resolve) => { + broadcastListener.callback = (channel, message) => { + expect(channel).toEqual("y-js") + expect(message.message instanceof Uint8Array).toBe(true) + + clearTimeout(timeout) + timeout = setTimeout(() => resolve(), 1000) + } + + pathID = room.addPath(pathDraw[0]) + for (let i = 1; i < pathDraw.lenth; i++) { + room.extendPath(pathID, pathDraw[1]) + } + }).then( + () => + new Promise((resolve) => { + broadcastListener.callback = (channel, message) => { + expect(channel).toEqual("y-js") + expect(message.message instanceof Uint8Array).toBe(true) + + clearTimeout(timeout) + timeout = setTimeout(() => resolve(), 1000) + } + + for (let i = 0; i < pathErase.length; i++) { + room.extendErasureIntervals( + pathID, + pathErase[i][0], + pathErase[i][1], + ) } }), )