简体   繁体   中英

JS Worker Performance - Parsing JSON

I'm experimenting with Workers as my user interface is very slow due to big tasks running in the background.

I'm starting at the simplest tasks such as parsing JSON. See below for my very simple code to create an async function running on a Worke.

Performance wise there is a big difference between:

JSON.parse(jsonStr);

and

await parseJsonAsync(jsonStr);

JSON.parse() takes 1ms whereas parseJsonAsync takes 102ms!

So my question is: are the overheads really that big for running worker threads or am I missing something?

const worker = new Worker(new URL('../workers/parseJson.js', import.meta.url));

export async function parseJsonAsync(jsonStr) {

    return new Promise(
        (resolve, reject) => {

            worker.onmessage = ({
                data: {
                    jsonObject
                }
            }) => {
                resolve(jsonObject);
            };

            worker.postMessage({
                jsonStr: jsonStr,
            });
        }
    );
}

parseJson.js

self.onmessage = ({
    data: {
        jsonStr
    }
}) => {

    let jsonObject = null;

    try {
        jsonObject = JSON.parse(jsonStr);
    } catch (ex) {

    } finally {
        self.postMessage({
            jsonObject: jsonObject
        });
    }
};

I share my benchmark code below. You can play around yourself.

You can tune the number of item in jsonStr by changing Array.from({ length: number }) . Or you can compare runTest(1000) vs runTest() to see time diff btw waiting for worker to start or not.

My test shows it takes around 30ms to start the worker. Now if I wait a second for the worker to start, then I run the test, I got these numbers (unit in milliseconds):

#items main worker
1,000 0.2 2.1
10,000 1.3 9.8
100,000 15.4 73.5
1,000,000 165 854
10,000,000 2633 15312

 const blobURL = URL.createObjectURL( new Blob( [ "(", function () { self.onmessage = ({ data: { jsonStr } }) => { let jsonObject = null; try { jsonObject = JSON.parse(jsonStr); } catch (ex) { } finally { self.postMessage({ jsonObject: jsonObject, }); } }; }.toString(), ")()", ], { type: "application/javascript" } ) ); const worker = new Worker(blobURL); const jsonStr = "[" + Array.from({ length: 1000 }, () => `{"foo":"bar"}`).join(",") + "]"; async function parseJsonAsync(jsonStr) { return new Promise((resolve) => { worker.onmessage = ({ data: { jsonObject } }) => { resolve(jsonObject); // tiem end here const delta = performance.now() - t0; console.log("main-worker", delta); parseJsonInMain(jsonStr); }; const t0 = performance.now(); worker.postMessage({ jsonStr: jsonStr, }); }); } const test = () => parseJsonAsync(jsonStr); function runTest(delay) { if (delay) { setTimeout(test, delay); } else { test(); } } function parseJsonInMain(jsonStr) { let obj; try { const t0 = performance.now(); obj = JSON.parse(jsonStr); const delta = performance.now() - t0; console.log("main", delta); } catch {} } runTest(1000);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM