diff --git a/README.md b/README.md index d02116a..0295e61 100644 --- a/README.md +++ b/README.md @@ -104,8 +104,7 @@ A file webfftWrapper.js will exist in all sub-library dirs, so that we can avoid ### How to build and run our benchmarks 1. `npm install` -2. `npm run build` -3. `npm install --global serve` +2. `npm install --global serve` 4. `npm run serve` 5. Open your browser to http://localhost:8080 diff --git a/examples/basicUsage.js b/examples/basicUsage.js index 1dfe105..bfad34c 100644 --- a/examples/basicUsage.js +++ b/examples/basicUsage.js @@ -19,3 +19,5 @@ for (let i = 0; i < fftsize; i++) { } const outputArrReal = fft.fftr(inputArrReal); console.log(outputArrReal); + +fft.dispose(); diff --git a/examples/profile.js b/examples/profile.js index bdd43d6..b4dba0a 100644 --- a/examples/profile.js +++ b/examples/profile.js @@ -5,6 +5,7 @@ import webfft from "../lib/main.js"; const fftsize = 1024; const fft = new webfft(fftsize); const profileObj = fft.profile(2); // duration to run profile, in seconds +fft.dispose(); console.log(profileObj); console.log("Fastest sub-library:", profileObj.fastestSubLibrary); diff --git a/lib/@types/webfft/index.d.ts b/lib/@types/webfft/index.d.ts index aff2aee..a5490de 100644 --- a/lib/@types/webfft/index.d.ts +++ b/lib/@types/webfft/index.d.ts @@ -5,6 +5,7 @@ export default class webfft { availableSubLibraries(): string[]; profile(duration?: number): ProfileResult; checkBrowserCapabilities(): Promise; + dispose(): void; } export interface ProfileResult { diff --git a/lib/benchmark.js b/lib/benchmark.js index cf0c096..105065d 100644 --- a/lib/benchmark.js +++ b/lib/benchmark.js @@ -16,9 +16,10 @@ window.onload = function () { const fft = new webfft(fftsize); const profileObj = fft.profile(duration); + fft.dispose(); console.log(profileObj); - let results = profileObj.ffsPerSecond; + let results = profileObj.fftsPerSecond; let test_names = []; let barColors = []; @@ -43,8 +44,8 @@ window.onload = function () { x: xArray, y: yArray, type: "bar", - marker: { color: barColors } - } + marker: { color: barColors }, + }, ]; const layout = { @@ -54,9 +55,9 @@ window.onload = function () { text: "FFTs per Second", font: { family: "sans serif", - size: 18 - } - } + size: 18, + }, + }, }, annotations: [ { @@ -67,8 +68,8 @@ window.onload = function () { font: { family: "sans serif", size: 18, - color: "rgba(255,0,0,1)" - } + color: "rgba(255,0,0,1)", + }, }, { x: 1, @@ -78,10 +79,10 @@ window.onload = function () { font: { family: "sans serif", size: 18, - color: "rgba(0,0,255,1)" - } - } - ] + color: "rgba(0,0,255,1)", + }, + }, + ], }; Plotly.newPlot("myPlot", sortDescending(data), layout); diff --git a/lib/index.html b/lib/index.html index 52b61e9..ac374eb 100644 --- a/lib/index.html +++ b/lib/index.html @@ -1,6 +1,6 @@ - + diff --git a/lib/main.js b/lib/main.js index ab18307..9058b7a 100644 --- a/lib/main.js +++ b/lib/main.js @@ -186,6 +186,12 @@ class webfft { async checkBrowserCapabilities() { return await checkBrowserCapabilities(); } + + dispose() { + if (this.fftLibrary && this.fftLibrary.dispose !== undefined) { + this.fftLibrary.dispose(); + } + } } export default webfft; diff --git a/lib/utils/replaceStrings.js b/lib/utils/replaceStrings.js deleted file mode 100644 index 38637ab..0000000 --- a/lib/utils/replaceStrings.js +++ /dev/null @@ -1,17 +0,0 @@ -import fs from "fs"; - -// Get command line arguments -let filename = process.argv[2]; -let oldString = process.argv[3]; -let newString = process.argv[4]; - -fs.readFile(filename, "utf8", function (err, data) { - if (err) { - return console.log(err); - } - let result = data.replace(new RegExp(oldString, "g"), newString); - - fs.writeFile(filename, result, "utf8", function (err) { - if (err) return console.log(err); - }); -}); diff --git a/lib/utils/sortPerformance.js b/lib/utils/sortPerformance.js index 1835a17..3367aa3 100644 --- a/lib/utils/sortPerformance.js +++ b/lib/utils/sortPerformance.js @@ -4,8 +4,16 @@ function sortDescending(data) { let yArray = data[0].y; let barColors = data[0].marker.color; + if (!yArray || yArray.length == 0) { + return data; + } + // Create an array of objects from xArray, yArray, and barColors - let combined = xArray.map((x, i) => ({ x: x, y: yArray[i], color: barColors[i] })); + let combined = xArray.map((x, i) => ({ + x: x, + y: yArray[i], + color: barColors[i], + })); // Sort combined array by 'y' property in descending order combined.sort((a, b) => b.y - a.y); @@ -21,8 +29,8 @@ function sortDescending(data) { x: sortedXArray, y: sortedYArray, type: "bar", - marker: { color: sortedBarColors } - } + marker: { color: sortedBarColors }, + }, ]; return sortedData; diff --git a/package.json b/package.json index cf7cbb7..d10db39 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,7 @@ "main": "lib/main.js", "types": "lib/@types/webfft/index.d.ts", "scripts": { - "serve": "node ./lib/utils/replaceStrings.js lib/index.html \"benchmark\" \"dist/bundle\" && serve lib -l 8080", - "serve_dev": "node ./lib/utils/replaceStrings.js lib/index.html \"dist/bundle\" \"benchmark\" && serve lib -l 8080", + "serve": "serve lib -l 8080", "build": "webpack --config ./webpack.config.cjs --output-path ./lib/dist", "test": "vitest --config ./tests/vitest.config.ts" }, diff --git a/site/src/components/BenchmarkSection.tsx b/site/src/components/BenchmarkSection.tsx index f3763e6..6d7cfae 100644 --- a/site/src/components/BenchmarkSection.tsx +++ b/site/src/components/BenchmarkSection.tsx @@ -51,6 +51,7 @@ function BenchmarkSection({ .catch((error) => { console.error("Failed to check browser capabilities:", error); }); + webfftInstance.dispose(); }, []); useEffect(() => { diff --git a/site/src/docs/GettingStarted.mdx b/site/src/docs/GettingStarted.mdx index 39fa638..ac75555 100644 --- a/site/src/docs/GettingStarted.mdx +++ b/site/src/docs/GettingStarted.mdx @@ -38,6 +38,9 @@ const out = fft.fft(input); // out will be a Float32Array of size 2048 const out = fft.fft(input, 'indutny'); //or const out = fft.fft(input, profileResults[0]['SubLibraryName']); // profileResults obj will likely be changed later + +// Dispose (release Wasm memory, etc.) +fft.dispose(); ``` ### Sub-Library API diff --git a/site/src/utils/webworker.tsx b/site/src/utils/webworker.tsx index ef76eaf..26e8302 100644 --- a/site/src/utils/webworker.tsx +++ b/site/src/utils/webworker.tsx @@ -6,6 +6,7 @@ onmessage = (e: MessageEvent<[number, number]>) => { const [fftSize, duration] = e.data; const fft = new webfft(fftSize); const profileObj: ProfileResult = fft.profile(duration); + fft.dispose(); self.postMessage(profileObj); }; diff --git a/tests/fft.test.js b/tests/fft.test.js index ee52acf..0b0d721 100644 --- a/tests/fft.test.js +++ b/tests/fft.test.js @@ -11,12 +11,14 @@ test("basic usage", () => { const outputArr = fft.fft(inputArr); expect(outputArr[0]).not.toBe(0); expect(outputArr.length).toBe(2 * fftsize); + fft.dispose(); }); test("available sublibraries", () => { const fft = new webfft(1024); const availableSubLibraries = fft.availableSubLibraries(); expect(availableSubLibraries.length).toBeGreaterThan(1); + fft.dispose(); }); test("outputs for all sublibs approx match using different fftsizes", () => { @@ -57,6 +59,8 @@ test("outputs for all sublibs approx match using different fftsizes", () => { } expect(Math.abs(total - goldenTotal)).toBeLessThan(goldenTotal * 1e-7); } + + fft.dispose(); } }); @@ -90,6 +94,8 @@ test("fftr", () => { } expect(Math.abs(total - goldenTotal)).toBeLessThan(goldenTotal * 1e-7); } + + fft.dispose(); }); test("int16 inputs", () => { @@ -122,4 +128,6 @@ test("int16 inputs", () => { } expect(Math.abs(total - goldenTotal)).toBeLessThan(goldenTotal * 1e-7); } + + fft.dispose(); }); diff --git a/tests/profile.test.js b/tests/profile.test.js index 8248b7b..8e1e802 100644 --- a/tests/profile.test.js +++ b/tests/profile.test.js @@ -10,4 +10,5 @@ test("run profile", () => { const elapsed = (performance.now() - start) / 1e3; expect(elapsed).toBeGreaterThan(duration); expect(elapsed).toBeLessThan(duration * 1.5); // possibility for this to error in the future if run on a super slow machine + fft.dispose(); });