Skip to content

Instantly share code, notes, and snippets.

@RickCarlino
Created May 6, 2023 03:21
Show Gist options
  • Save RickCarlino/56d10e881eb032878ff7115c115971a4 to your computer and use it in GitHub Desktop.
Save RickCarlino/56d10e881eb032878ff7115c115971a4 to your computer and use it in GitHub Desktop.
Konilo interpreter optimization to not block event loop.

The Konilo interpreter execs byte code in a loop. The Javascript VM cannot do anything else while this loop is running unfortunately, so the browser is unresponsive until all bytecode has executed.

The modification below adds an artificial sleep() function that allows the event loop to catch its breath and service event handlers (eg: UI clicks, form interaction, unrelated AJAX calls, etc...)

The EVENT_LOOP_PAUSE_TICKS variable will need to be tuned to find a balance between initial load speed and UI responsiveness.

Other ideas:

  • Use an HTML gauge element to show loading progress when loading initial image.
  • Use different tick sizes on initial load vs. program runtime.
      async function sleep(ms) {
        return new Promise((resolve) => setTimeout(resolve, ms));
      }

      async function execute() {
        input = " " + document.getElementById("input").value + " \n";
        /*
        |Ticks |Load Time | Blockage        |
        |------|----------|-----------------|
        | 100  | 23,019ms | Not-Blocked     |
        | 200  | 21,927ms | Not-blocked     |
        | 350  | 6,438ms  | Not-Blocked     | <= Too slow
        | 425  | 22,334ms | Not blocked     | <= Anomaly (??) 
        | 500  | 3,746ms  | Not-Blocked     | <= Perfect?
        | 550  | 1,980ms  | Slight blockage | <= Too fast.
        | 600  | 1,996ms  | Slight blockage |
        | 700  | 1,932ms  | blocked         |
        | 1000 | 1,954ms  | Blocked         |
        */
        // Tune this value to find a balance between speed and
        // event loop blockage.
        const EVENT_LOOP_PAUSE_TICKS = 500; // TODO: tune this.
        while (input.length >= 1 && !isNaN(ip)) {
          var o = m[ip];
          process(o & 0xff);
          process((o >> 8) & 0xff);
          process((o >> 16) & 0xff);
          process((o >> 24) & 0xff);
          ip = ip + 1;

          if (ip % EVENT_LOOP_PAUSE_TICKS === 0) {
            await sleep(0);
          }
        }

        document.getElementById("input").value = "";
        console.log("done");
        document.getElementById("display").scrollTop =
          document.getElementById("display").scrollHeight;
      }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment