July 11th, 2024

Some Tricks from the Scrapscript Compiler

The Scrapscript compiler implements optimization tricks like immediate objects, small strings, and variants for better performance. It introduces immediate variants and const heap to enhance efficiency without complexity, seeking suggestions for future improvements.

Read original articleLink Icon
Some Tricks from the Scrapscript Compiler

The article discusses optimization tricks implemented in the Scrapscript compiler, focusing on immediate objects, small strings, and variants. Immediate objects allow encoding small integers and strings directly into pointers without heap allocation. Small strings use 7 bytes for data and 1 byte for a tag, optimizing string storage. Variants, similar to OCaml, are dynamically typed and retain tags at runtime for pattern matching. The compiler now supports immediate variants like #true() and #false(), improving performance by avoiding heap allocation. Additionally, the article introduces the const heap, which optimizes constant data structures like lists by pre-allocating them as C globals. These optimizations aim to enhance runtime efficiency without significantly increasing complexity. The article concludes by inviting suggestions for further compiler and runtime enhancements in Scrapscript.

Related

Optimizing the Roc parser/compiler with data-oriented design

Optimizing the Roc parser/compiler with data-oriented design

The blog post explores optimizing a parser/compiler with data-oriented design (DoD), comparing Array of Structs and Struct of Arrays for improved performance through memory efficiency and cache utilization. Restructuring data in the Roc compiler showcases enhanced efficiency and performance gains.

Spending too much time optimizing for loops

Spending too much time optimizing for loops

Researcher Octave Larose shared insights on optimizing Rust interpreters, focusing on improving performance for the SOM language. By enhancing loop handling and addressing challenges, significant speedups were achieved, balancing code elegance with efficiency.

Weekend projects: getting silly with C

Weekend projects: getting silly with C

The C programming language's simplicity and expressiveness, despite quirks, influence other languages. Unconventional code structures showcase creativity and flexibility, promoting unique coding practices. Subscription for related content is encouraged.

Spending too much time optimizing for loops

Spending too much time optimizing for loops

Researcher Octave Larose discussed optimizing Rust interpreters, focusing on improving performance for the SOM language. They highlighted enhancing loop efficiency through bytecode and primitives, addressing challenges like Rust limitations and complex designs. Despite performance gains, trade-offs between efficiency and code elegance persist.

Beating the Compiler

Beating the Compiler

The blog post discusses optimizing interpreters in assembly to outperform compilers. By enhancing the Uxn CPU interpreter, a 10-20% speedup was achieved through efficient assembly implementations and techniques inspired by LuaJIT.

Link Icon 1 comments
By @Joker_vD - 3 months
> "Foo | Bar variants are stored as ascending OCaml ints, starting from 0." I was initially worried that OCaml could only do this because they have type inference and therefore the compiler knows much more about what type every AST/IR node is.

No, they are able to do that because they have static typing and they don't have to distinguish between values of "type A = FooA | BarA" and "type B = FooB | BarB" at run-time, so they can represent FooA, FooB, 0, false, unit etc. all the same. They can't do the same with their "extensible variants" though, so those IIRC are encoded as objects.

Wait, how does Scrapscript distinguish between values of different types? Say,

    . scoop :
      #vanilla
      #chocolate
      #strawberry
    . f =
      | #vanilla -> 1
      | #false   -> 2
      | x        -> 999
Is that legal? If yes, how does it work?