I just hit the instruction limit!

Are you thinking this for general JS interpretation or just for crypto operations?

I meant it for general JS interpretation, but crypto operations are probably at the top range.

Note that the numbers I wrote were based on my intuition from seeing a few examples. Maybe my impression was biased due to the slow JS candid implementation.

To get more concrete numbers, I did a small experiment: a program that computes sum((i % 100)^2) for all 0 <= i < 1M. The expression was chosen to make it difficult for the compiler to optimize it away.

Here are the results:

  • Rust: instructions: 13_761_694, sum: 3_283_500_000
  • Motoko: instructions: 92_001_970, sum: 3_283_500_000
  • Azle: instructions: 1_341_172_853, sum: 3_283_500_000

In this experiment Azle is 97x slower than Rust and 14x slower than Motoko.

I corrected 100x-1000x to 10x-100x in my post based on these results.

At least the QuickJS benchmarks put it about 35x less performant than JIT V8.

Assuming that V8 is close to native, I wonder if there is a factor of ~3x that’s missing here?

Attaching the source code of programs in case anyone wants to double check.

#[ic_cdk::query]
fn bench() -> String {
    let mut sum: i64 = 0;
    for i in 0..1_000_000 {
        sum += (i % 100) * (i % 100); 
    }
    format!("instructions: {}, sum: {}", ic_cdk::api::performance_counter(0), sum)
}
import IC "mo:base/ExperimentalInternetComputer";
import Nat64 "mo:base/Nat64";

actor {
  public query func bench() : async Text {
    var sum : Nat64 = 0;
    var i: Nat64 = 0;
    while (i < 1_000_000) {
       sum += (i % 100) * (i % 100);
       i += 1;
    };
    let instructions = IC.performanceCounter(0);
    return "instructions: " # Nat64.toText(instructions) # ", sum: " # Nat64.toText(sum);
  };
};
import { IDL, query, update, instructionCounter } from 'azle';

export default class {
    @query([], IDL.Text)
    bench(): string {
        let sum = 0;
        for (let i = 0; i < 1_000_000; ++i) {
            sum += (i % 100) * (i % 100);
        }
        let instructions = instructionCounter(0);
        return `instructions: ${instructions}, sum: ${sum}`;
    }
}
4 Likes