Mica is a statically typed systems language with its own optimizing native backend — no LLVM, no GCC backend, no third-party dependency anywhere in the implementation. It is influenced by Pascal, Ada, and C. Three commitments shape everything on this page: the compiler proves at compile time what would otherwise be found in the debugger; a program’s output is deterministic to the digit — run after run on one machine, at every optimization tier, and even across serial and parallel execution, with C’s own bits on both architectures for every exactly rounded operation; and the numeric stack up to a training loop on a GPU is part of the language, not a package ecosystem bolted on.
Everything below can be checked in an afternoon: the compiler is free for any
use including commercial, and docker run -it micalang/mica is a complete
environment — compiler, debugger, examples, benchmarks.
What the compiler proves at compile time
Each row is a hard guarantee with its own documented mechanism, not a lint:
| Guarantee | Mechanism |
|---|---|
| Heap lifetimes | every allocation is an obligation with exactly four discharges — dispose, defer, return, or owner binding — and a call whose result hands cells over, an owning pointer or a record with an owning field, binds its caller the same way; an owning field overwritten while it still holds a cell nothing released is refused at the store that loses it (13110); use-after-free and double-free are compile-time reports, with no garbage collector, no borrow checker, and no lifetime annotations |
| Data-race freedom | every touch of shared state must sit under synchronized; a call cannot launder a shared access; proved at compile time, and the compiler’s own test gate runs under a race detector |
| Task lifetimes | the task tree is the scope tree: a concurrent block joins every task it started on every exit path — no detached thread exists in the language |
| Array and tensor bounds | indices are checked against the type’s own bounds at compile time where provable, trapped at a named source line where not; the optimizer removes only the checks it has proven away |
| Tensor shapes | vector[N] and matrix[R, C] carry shape in the type — a product whose dimensions cannot meet is refused before the program exists |
| Format strings | checked against their arguments at compile time, under either string encoding |
| Failure handling | a fails function cannot be called without visibly consuming the failure — the compiler makes every call finish the story |
| Case totality | a case over an ordinal domain or a sum type answers every value and every case, or names its default; an arm reads a case’s fields only where it matched that case |
| Value transport | a task, a generator, a stream element and a task on another process each receive their own copy — text, arrays and the records and sums holding them, to any depth — and a pointer or a borrowed view, which no copy can own, is refused by its path from the parameter (5318, 5370); a typed transfer to a file or a connection carries only plain values, whose bytes are the value, and text reaches C in C’s own NUL-terminated shape, so a heap descriptor’s bytes never travel as data |
| C handles | a C library’s object is an opaque type Mica holds only through the handle its library answers — never by value or through new (5607), never read through (5608), never disposed by Mica’s allocator (5609), never sent to another process (5605), and handed to a task running beside its owner only when its contract states it thread_safe (5610) |
| Borrowed views | a span borrow is formed at a visible Span, lives inside a lifetime the caller can see, and freezes growth of what it borrows |
The rule behind the table is deliberate. Mica proves at compile time what is provable, and for the scenarios today’s analysis cannot prove, a checked build plants a trap: the program stops at a named source line instead of proceeding corrupted. A leak takes the same road: a cell the analysis could not follow, and nothing released, ends a checked run with a report naming each such cell by its type, its size and the file, line and column that made it. This is the language’s chosen middle way — no ownership model, no borrow checker, no lifetime annotations — because readability and low complexity for the developer are a top priority of the design, not an afterthought. Where a guarantee is usually bought with annotation machinery, Mica researches the pragmatic road to the same result: prove what the compiler can see, trap loudly on what it cannot yet, and move scenarios from the second list to the first with each release. The same discipline governs efficiency and footprint — small binaries, small images, and no runtime cost for features a program does not use.
What stays exact at run time
Determinism in Mica is a language property, not a library option:
- The same digits, run after run. The same program on the same machine
gives the same result at every optimization tier — C’s own promise. Every
operation IEEE 754 rounds exactly gives C’s bits on x86-64 and AArch64
alike, and the whole test corpus is gated on both architectures per
release;
Exp,LnandTanhare the C library’s own functions, whose last digit is the machine’s library’s. - Parallel equals serial. Reductions (
Sum,Mean, the extremes) run on one documented pairwise tree — the same tree serially and in parallel, so a float reduction gives bit-identical answers at every carrier count. A multicore run of the SIMD benchmarks is bit-identical to the serial run. - Checked arithmetic. At the checked tier, integer overflow traps at a named source line — scalar and tensor alike — instead of wrapping silently.
- Reproducible randomness. The
randomunit is seeded and bit-stable on every machine; a shuffled benchmark shuffles identically everywhere.
The practical consequence: a training run prints the same loss column every time it runs on the same machine, on the processor and on the graphics card alike. That claim is on the AI course, where every chapter keeps it.
Machine learning inside the language
Not a framework: language surface, with the compiler’s checks applied to it.
- Autograd is a language feature.
trackedvalues record onto a tape inside atape … endwindow; oneBackwardwalk answers every gradient throughGradient. A function of one’s own over tracked values, a library’s included, records its body when the window calls it. The recorded vocabulary — the tensor operators plusSum,Tanh,Softmax,LayerNorm,CrossEntropyand their family — keeps each verb’s plain signature and shape rules. - The GPU is a residency, not a dialect. A tensor declared
on gpukeeps its type and moves its storage; values cross only at visibleToDevice/ToHost. The tensor verbs dispatch to the device by residency, through NVIDIA’s own libraries — cuBLAS for the products, and kernels the compiler writes in CUDA C for NVRTC to build on the machine — so an NVIDIA card of compute capability 7.5 or newer (the Turing generation of 2018 and everything after it), with its driver, cuBLAS and NVRTC, is the whole requirement. A device training run leaves the same learned weights, byte for byte, every time it runs on the same card. - A GPT is the worked example. The
Gptexample that ships with the container trains a 786944-parameter transformer with every mechanism above — walked chapter by chapter in the twelve-chapter AI course, from the first nudge loop to text in your corpus’s style, reproducible to the digit.
The language, briefly
- Values are values. Assignment and argument passing copy, all the way
down; sharing is a visible
pointer, anaddresswritten at the call, avalueat every touch — never a hidden reference. - Errors are a channel, not a convention.
failsin the signature,failto raise, four visible consumption forms at the call — no return codes to forget, no exceptions, no result value to unwrap; C’s errno is lifted into typed codes at the boundary by contract. - Sum types. An enumeration whose cases carry named field sets: a value
holds exactly one case, and every
caseover it answers every case — walked in sum types. - Concurrency is structured. Tasks, generators, streams over bounded
rings,
selectwith timeout — with the join guaranteed by scope and the capture discipline checked at compile time. Ascheduleending inon processruns the task or generator in a worker process of the program instead: it shares nothing, receives its own copies and the descriptors themselves, and a trap there ends that worker alone, which the program answers in anon lostsection — walked in tasks on processes. - Generics with capability constraints. One algorithm over many types,
monomorphized; constraints (
numeric,ordinal,plain, …) are checked against the body and every call. - Memory is a deployment class. The same source links against the
hosted heap or a fixed arena —
--memory-class fixed-arena=<bytes>, no code change. A program can run with no heap at all, and indefinitely: drained regions return their blocks for reuse, so a long-running loop’s live set stays bounded inside the fixed budget. Both classes compose with single and multicore tasking, and the test corpus runs under both. A program that ends normally hands back every block its runtime holds — the regions and the spare blocks kept for reuse, the scheduler’s tables, and on the multicore flavor its joined carriers — so a memory checker finds nothing still reachable at exit; anexitcalled while tasks run ends the process at once, with the status it asked for. The memory-classes tutorial walks it end to end, and Technical Report 1 states the model whole. - Callbacks without function pointers. A C library that calls back into your program names the routine at a contract’s callback slot; the routine is never a value and never called from Mica — the third declared subprogram kind, walked in callbacks at the boundary.
- Routines that never touch the heap.
heaplesson a routine’s heading is a promise the compiler checks: every construct that would allocate or release is refused at its own line, a heapless routine calls only routines that promise the same, and a contract carries the promise across units — walked in heapless routines. - Signal handlers the compiler checks. A
heapless callbackinstalled withSignalHandlemay not allocate, wait or take a lock, judged through every call it makes and every contract, and it hands the real work to a task throughSignalWake— walked in signal handlers. - Two build-time string encodings. UTF-32 as the general default, UTF-8 for the boundary — one letter of difference in format specifiers, checked at compile time.
What ships in the language
The standard library is written in Mica — seventeen units, resolved by plain
imp, no package manager required:
| Unit | What it carries |
|---|---|
std | the language core: text output, Backward, Gradient, Length, Resize, Reshape, the everyday surface |
math | the one home of Mica’s mathematics: the intrinsics the compiler realizes at the call site (Sqrt and FusedMultiplyAdd as the processor’s instructions, Exp, Ln and Tanh as the C library’s functions of the operand’s width), generic scalar verbs at full type fidelity, the tensor verb vocabulary (Sum, Softmax, LayerNorm, CrossEntropy, …) and the tensor kernels (Dot, Transpose, Conv2d, Gather, …), slicing (Row, Column, SubMatrix, Window), constants, IEEE classification |
arrays | Sort (native generic heapsort), Insert, Remove, SubArray, List, the dynamic-array verbs |
strings | the string verbs over the two-field immutable value, the stringbuffer builder, the stringpart window |
maps | the typed associative container under the value rule |
linalg | Solve, Invert, Cholesky and Qr over dynamic matrices, singularity as an expected answer on the failure channel |
integers | the wide family’s int128…uint256 names and the unbounded bigint with verb arithmetic |
files | the typed file over the failure channel |
paths | pure, total path algebra beside the directory walk |
process | the environment a program was started in — read, write, enumerate — its own identity, arguments and exit status, and the programs it starts: spawn with wired pipes, wait, poll, terminate, kill (from 7.6) |
flags | a command line declared before it is read: typed flags, one parse, typed readers, and the help text generated from the declarations (from 7.6) |
net | connections as values: servers, clients, framed typed transfers, deadlines, and same-host endpoints that admit only their own user unless opened shared |
streams | stream adapters over the pull-and-push machinery |
random | seeded, bit-stable generation and shuffling |
time | a monotonic Now whose differences alone carry meaning, duration constants (250 * Millisecond), and a Sleep no signal cuts short |
regex | patterns compiled to a linear-time engine no input can make pathological |
utf | text as interchange bytes and back: encode, validate, strict and lossy decode, and a cursor that decodes a chunked stream without losing a code point cut by a boundary |
Beneath them, the C standard library, POSIX, and Linux surfaces ship as
26 curated contracts embedded in the compiler binary — imp Open : posix; works on a fresh install with nothing else on disk, every call
type-checked, every errno lifted into the failure channel. The Dragon SDK’s
own surface is the 27th, for programs that drive the backend.
The toolchain
| Current version | 7.7.2 |
| Targets | Linux x86-64 (x86-64-v3) · Linux AArch64 (ARMv8.0-A) |
| Code generation | own backend, source to ELF — the GNU as and ld, and ar for a static library, are the only tools a build runs, beside the target’s pkg-config when a C library’s contract names its package |
| Cross-building | either architecture from either host, same flags |
| Debug information | DWARF v5 — gdb works on Mica binaries out of the box, across the C boundary and into generic instantiations |
| Optimization levels | O0 (debug): every value on the stack, every variable observable, the allocation site of every cell recorded; O1 (release,standard_optimizations): constant folding and the assembly peephole; O2 (release,full_optimizations): inlining, the loop optimizations and the graph-colouring register allocator besides; checked beside either profile — O2,checked ships every guard on the optimizing lowering; profiling beside any set keeps the line table, the subprogram entries and the inlining records with the release build’s code to the byte — what each level does |
| Profiling | a build without --strip names every procedure by its flat name, and every tier carries call-frame information, so perf unwinds a release binary, callgrind attributes instructions to source lines, and gdb names an inlined callee as its own frame — profiling a Mica program |
| Shipping shape | --static links the program wholly, so it runs on a machine with no C library — one file in a FROM scratch image; --strip removes the symbol table |
| What a program carries | stripped, at O2: a hello world 52 KB on x86-64 and 68 KB on AArch64, an everyday program 77 KB and 134 KB, a concurrent one 68 KB and 68 KB; every ladder holds them to their sizes within one percent |
| Deployment | --memory-class hosted-heap or fixed-arena=<bytes> and --tasking single or multicore[,carriers[,fixed]] select the matching runtime archive at link time, a multicore pool running 1 to 1024 carriers; --processes bounds the worker processes running at once, 1 to 1024; --stack-size gives large frames their stack |
| Remarks | --remarks lets the compiler speak its third voice beside errors and warnings: a fact about your code and the alternative it names, never gating a build — a dynamic array a loop makes with no variable to hold it, for one, is named with the activation that keeps its backing (5613) — every remark |
| The exported compiler | --export writes every intermediate representation to the build directory, so the compiler’s own reading of a program can be read — the compiler, exported; --profile times every phase and pass of a compile |
| Library contracts | a Mica library’s import surface is a mica.external beside its archive, emitted with --emit-contract, carrying the library’s version, its interface digest and every exported type’s fingerprint, so another unit imports the library by resolving the contract — the format |
| Versions | a library links only under the version its mica.project states, and a program’s project states which versions of each library it accepts (requires, read as Cargo and npm read a requirement); a build refuses, by the library’s name, a contract outside that range, an archive of another build than the contract it compiled against, a standard library or runtime floor another compiler made, and a C library below the minimum its contract names, as the target’s pkg-config answers |
| The project file | mica.project beside the sources names the sources, the encoding, the contracts, its own version and the versions of each library it accepts; the compiler, the run mode and the editor read the same file — the project file |
| Build manifest | every program, archive and shared object carries its manifest — its own version, the compiler’s release and commit, the platform and encoding, the optimization set, the memory class, the tasking and worker counts, and every library it was built against with its version — in a read-only section a stripped program keeps; mica --inspect prints it without starting the program — the program manifest |
| Quality gates | --quality runs the compiler’s two internal gates on a compile — after semantic analysis and after intermediate-code generation — so an internal error is root-caused at the phase that introduced it; every test program compiles with both on — how we verify |
| Editor support | a language server inside the compiler (mica --language-server); VS Code extension as the packaged client, with Mica Notebooks — Mica in a Markdown document whose recorded outputs are re-verified — and a runtime view in which the program explains its own tasks, its autograd tape and the memory it holds |
| Scripting | mica tool.mica compiles and runs like a script; #!/usr/bin/env mica works |
| The C ABI | both directions by declared contract: Mica calls C libraries type-checked, each C failure convention — a negative, null or sentinel return read with errno, or a status code that is its own reason — lifted onto the failure channel, and a Mica archive links into a C program with no runtime to initialize |
| Install | four roads: the dev container, the image micalang/mica, the Debian packages for both architectures, or a machine in the cloud the devkit creates and removes |
| Licence | MCL-1.0 — free for any use, including commercial; not open source; every program you compile is wholly yours — licensing |
| Dragon SDK | the backend as a C API for building your own language — a separate package, free for noncommercial use |
What the packages install
Three Debian packages, every program and library file each one puts on the machine, and the file’s size as built for 7.7.2. Beside them the packages place only their licence texts and changelogs and, in the SDK’s documentation directory, a copy of the engine’s import surface to read beside the header. Nothing else is installed: no runtime service, no contract file a build reads, no toolkit.
| Package | File | ARM64 | AMD64 |
|---|---|---|---|
mica | /usr/bin/mica — the compiler, the language server, every import surface, one binary | 16.7 MB | 18.3 MB |
mica | /usr/lib/mica-stdlib-<arch>.a — the standard library | 781 KB | 759 KB |
mica-dragon-rt | /usr/lib/mica-dragon-rt[-sites][-fixedarena][-mc]-<arch>.a — the runtime floor every program links: four class variants, each built again to record every cell’s allocating site for the debug tier; one linked | 748 KB to 819 KB each | 736 KB to 798 KB each |
mica-dragon-rt | /usr/lib/mica-dragon-gpu-<arch>.a — the device floor, linked when a tensor is placed on gpu | 6617 KB | 6601 KB |
mica-dragon-sdk | /usr/lib/mica-dragon-<arch>.a — the backend engine for a frontend of your own | 26.6 MB | 24.7 MB |
mica-dragon-sdk | /usr/include/mica_dragon.h — the engine’s C header | 33 KB | 33 KB |
A compiled program is one self-contained binary; nothing from these packages
travels with it, and --static makes it a binary that runs on a machine with
no C library at all. The install page shows the same files
as a directory tree.
Where performance stands
Stated the way we measure it, so you can re-measure it:
- The backend is our own, and its optimizer earns its keep: the benchmark corpus retires 46.9% fewer instructions than unoptimized code, with bounds checks proven away rather than merely hoisted.
- Lane-level SIMD reaches 2.33x over scalar on f64 and 4.03x on f32; data-parallel execution on 8 cores reaches up to 4.0x — bit-identical to the serial result at every carrier count.
- On general-purpose code,
gcc -O2still leads; specific numeric loops reach or pass parity. We publish the gap and work on it each release — performance and method carries the numbers and the measurement discipline. - The benchmarks live in the container you can pull:
benchmarks/besideexamples/, each amakeaway, oracle-checked so a wrong answer fails loudly before a fast one impresses anyone.
Where we are — benchmarks and tests, stated plainly
The two questions a reader of this page asks are how fast the code is and how well the compiler is tested. Both are answered by running, not by asserting, and both answers are dated.
Benchmarks. Ten kernels of the Computer Language Benchmarks Game are
implemented twice, in Mica and in C with the identical algorithm, and run on
named Google Cloud machine types anyone can rent, both compilers at O2, every
Mica safety check on. By wall clock, eight of ten kernels stand within two
times of gcc -O2 on ARM64 and within one and a half times on AMD64; the two
set beside that band measure an allocator and a regular-expression engine
respectively, the regex kernel running ahead of C’s engine on ARM64, and the
tables below name the procedures every kernel’s time goes to. Peak memory is
measured
beside time and held within a per-kernel budget, and the standard library’s
operations are priced per call. The run is repeated at every release, and
between releases every kernel runs under callgrind at every merge and must
stay within one percent of its pinned instruction count
(23 kernels pinned today). The tables below carry the
machine, the date and the compiler’s own version line.
Tests. 2,847 test programs declare 17,627 runs across every optimization tier, the checked tiers included, both memory classes and both architectures; 2,650 of them run on x86-64 and AArch64 alike. Every push to the compiler runs its pipeline’s fast checks, and every merge request into a release branch that changes the compiler runs the whole ladder on a cloud machine made for that job alone: the corpus three ways — the optimizing lowering under stress, the direct lowering, and the compiler’s own Go under the race detector — plus the multicore package gate, the C shim probe (68/0), the memory checker, the price gate and the compiler’s dependency gate (345 pinned package edges); last run, stress 17,363/0 · direct lowering 17,262/0 · race 17,262/0 · multicore 339/0 (runs / failures). The memory checker runs every heap, obligation, string, task, generator, stream, descriptor and signal case under valgrind, natively on the ladder machine, an AArch64 host (1,361/0 legs), and holds the programs that state it to end with nothing still reachable. Every compile of every test program runs the compiler’s two internal quality gates, which state every contract the code generator and the backends demand. A release is tagged only when the release gate finds every limit placed in it lifted and that ladder passed on exactly the tree the tag names, and its packages are built from that tag alone. At every release the same corpus additionally runs every Mica code block on this site through the released compiler, and its device cases and the GPU probe on real NVIDIA cards. Beyond the corpus, an adversarial sweep of 283 programs written to be wrongly accepted found 41 defects in 7.5, every one now a refusal that names its rule.
The numbers
| Implementation | 280,038 lines of Go in 910 files — zero third-party dependencies |
| Standard library | 96,416 lines of Mica and C — the units written in Mica and the runtime floor beneath them |
| Test corpus | 2,847 test programs · 17,627 declared test runs |
| Cross-architecture | 2,650 programs run on both architectures |
| Release ladder, last run | stress 17,363/0 · direct lowering 17,262/0 · race 17,262/0 · multicore 339/0 · C shim 68/0 · memory checker 1,361/0 — runs / failures, every gate on both architectures but the memory checker, which runs natively on AArch64 |
| Verification | every change that reaches the compiler’s code, tests or scripts passes the whole ladder before it merges into a release branch: the full corpus through the compiler, through a second and independent lowering path that must agree with it, and under Go’s race detector, with the multicore, C shim and memory-checker arms; every release adds the package proof on both architectures, the device cases and the GPU probe on real cards, and the tutorial gate — how we verify states every gate |
Figures generated from the repository at 2026-10-17 — no number on this page is typed by hand.
Measured — on machines anyone can rent
The numbers below are not typed into this page. Each is produced by one run of the benchmark suites on named, rentable Google Cloud machines, validated by the run itself, and rendered here from the run’s own files — the same files that write the container’s benchmark pages.
Measured 2026-09-28 on rented Google Cloud machines anyone can repeat the run on —
t2a-standard-4 (ARM64) and t2d-standard-4 (AMD64),
zone europe-west4-a, gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0, valgrind-3.22.0 —
with Mica Optimizing Compiler Version 7.6.5 3a04114b7. Both compilers at O2; every Mica safety check on; every Mica output
byte-identical to its C reference, and every library self-check identical on both machines, or the run is refused.
Execution time against gcc -O2 — the metric that matters. 8 of 10 kernels stand between 1.03x and 2.02x on ARM64 and between 1.04x and 1.50x on AMD64 (1.00x is parity, lower is Mica ahead). The remaining kernels measure an allocator and a regex engine respectively. Instruction counts (Ir) are the deterministic regression metric and overstate the gap: they count Mica's safety checks, which hide under memory latency on the clock.
Memory. Every kernel stood within its budget on both machines. Mica's peak resident set stands between 1.05x and 1.39x of gcc's on ARM64 and between 1.09x and 1.64x on AMD64, at most 684 KB and 1,040 KB above it — the runtime floor a Mica program carries whatever its work, largest in ratio where the kernel itself holds least. Peaks are the largest of three runs with transparent huge pages off for the process.
ARM64 — t2a-standard-4
| Kernel | wall | Ir | memory | wall (Mica / gcc) | peak KB (Mica / gcc) | note |
|---|---|---|---|---|---|---|
| RegexRedux | 0.61x | 0.52x | 1.33x | 53ms / 87ms | 2,776 / 2,092 | engine vs engine |
| SpectralNorm | 1.03x | 1.22x | 1.30x | 20ms / 19ms | 1,880 / 1,448 | parity class |
| PiDigits | 1.24x | 2.30x | 1.37x | 23ms / 19ms | 1,896 / 1,384 | |
| NBody | 1.25x | 1.32x | 1.39x | 15ms / 12ms | 1,928 / 1,384 | |
| Mandelbrot | 1.32x | 1.27x | 1.36x | 18ms / 13ms | 1,880 / 1,384 | |
| FannkuchRedux | 1.49x | 2.03x | 1.36x | 291ms / 195ms | 1,880 / 1,384 | |
| Fasta | 1.56x | 2.08x | 1.37x | 179ms / 115ms | 1,896 / 1,384 | |
| BinaryTrees | 1.58x | 1.55x | 1.05x | 648ms / 410ms | 10,076 / 9,580 | allocator-bound |
| ReverseComplement | 1.71x | 2.01x | 1.07x | 58ms / 34ms | 7,768 / 7,272 | |
| KNucleotide | 2.02x | 2.59x | 1.17x | 37ms / 18ms | 3,420 / 2,920 |
AMD64 — t2d-standard-4
| Kernel | wall | Ir | memory | wall (Mica / gcc) | peak KB (Mica / gcc) | note |
|---|---|---|---|---|---|---|
| Fasta | 1.04x | 2.45x | 1.64x | 166ms / 159ms | 2,376 / 1,448 | parity class |
| SpectralNorm | 1.08x | 1.57x | 1.16x | 18ms / 17ms | 2,328 / 2,000 | parity class |
| Mandelbrot | 1.22x | 1.08x | 1.62x | 17ms / 14ms | 2,448 / 1,512 | |
| ReverseComplement | 1.24x | 2.22x | 1.11x | 51ms / 41ms | 8,248 / 7,400 | |
| FannkuchRedux | 1.31x | 2.54x | 1.56x | 260ms / 198ms | 2,356 / 1,512 | |
| RegexRedux | 1.33x | 1.20x | 1.44x | 54ms / 41ms | 3,380 / 2,340 | engine vs engine |
| KNucleotide | 1.44x | 3.55x | 1.28x | 33ms / 23ms | 3,896 / 3,048 | |
| PiDigits | 1.49x | 2.55x | 1.43x | 24ms / 16ms | 2,344 / 1,640 | |
| NBody | 1.50x | 1.45x | 1.51x | 14ms / 9ms | 2,368 / 1,572 | |
| BinaryTrees | 1.72x | 1.54x | 1.09x | 427ms / 248ms | 10,548 / 9,708 | allocator-bound |
The standard library's prices — the cost per operation
Each row prices one operation over its own size and is read against its own history — the number a library change moves. The wall clock per operation leads (nanoseconds, the median of five runs, compared within one machine), the instruction count per operation is the deterministic price, and the peak resident set closes the row.
| Kernel | ns/op ARM64 | ns/op AMD64 | Ir/op ARM64 | Ir/op AMD64 | peak KB ARM64 | peak KB AMD64 | the operation priced |
|---|---|---|---|---|---|---|---|
| ArrayAppend | 31 | 39 | 112 | 98 | 3,892 | 4,244 | one Append through the doubling ladder |
| MapReaders | 57 | 52 | 345 | 361 | 5,888 | 6,204 | one Has or GetOr probe against fifty thousand entries |
| ArraySort | 192 | 173 | 936 | 918 | 2,872 | 3,224 | Sort, per element, over a hundred-thousand-element permutation |
| MapWriters | 254 | 264 | 963 | 713 | 9,792 | 10,136 | one Put through the growth ladder, or one Remove |
| StringScan | 775 | 684 | 4,617 | 5,313 | 1,984 | 2,500 | one Pos/Contains scan over a 4,600-character haystack |
| BigintArithmetic | 646 | 576 | 4,651 | 3,422 | 1,988 | 2,508 | one sixty-digit Add or Subtract |
| StringBuild | 978 | 859 | 5,921 | 5,792 | 1,984 | 2,376 | one Split or Join of a five-field line |
| RegexFind | 5,077 | 4,492 | 39,317 | 37,027 | 2,056 | 2,568 | one Find step of a match-by-match walk over a 4,000-character text |
| RegexScan | 15,679 | 17,488 | 151,444 | 124,692 | 1,992 | 2,560 | one compiled-pattern Count scan over an 88-character line |
| MathLayerStep | 47,514 | 34,600 | 327,523 | 367,349 | 2,180 | 2,708 | one layer verb over a 64×64 matrix |
Repeat it: devkit/mica-bench-cloud in the container image runs the same suites on the same machine
types and destroys the machines when done; devkit/mica-bench-render turns the run into these tables.
Add --profile NBody and the run brings one kernel's callgrind listings home beside the numbers, Mica beside its C twin.
Where to go next
Start · the compiler at a glance · how we verify · the technical reports · the reference · performance and method