On a long enough time frame with enough tokens invested there’s probably not a difference, but being written in assembly by an LLM doesn’t imply optimal to me. I’d almost prefer having an LLM rely on higher level abstractions offered by a programming language rather than rolling everything itself. After reviewing a lot of LLM code, even at Fable and Sol levels, I just don’t trust that LLMs are writing optimal code. Assembly makes it harder to even review.
I do it find it very fun and entertaining. This is a component and I’m grateful that it was shared.
Writing maintainable assembly is at odds with writing fast assembly in most circumstances.
A key optimization that's hard to pull off is inlining.
An optimizing compiler can see that a method is small enough that it can be pulled into the caller, it can then further eliminate from that smaller method branches that can't be executed due to the nature of the caller (Imagine calling a function with a `bool` parameter and you send in `true` at the call site).
To make the code faster in hand written assembly, you have to do the inlining, but that makes writing more structured code a lot harder. You are duplicating logic paths in the name of performance.
Not to mention the fact that the compiler gets updated and knows about more instructions and architectures then you do or then you could have. Hard to write the FMA instruction if it didn't exist when you were writing the assembly in the first place.
The other day, colleague showed me a (pretty basic) terminal emulator written in one-shot by Opus. Kicker is - that was compiled to a 30 KB static binary. That's right. No libX11, no libXfont, not even libc.
My terminal emulator using the same binding also started out hand-written but Claude overhauled that too recently and it knows vtxx escape codes far better than me too.
static inline long read(int fd, void *buf, long count) {
register long rax asm("rax") = __NR_read;
register long rdi asm("rdi") = (long)fd;
register long rsi asm("rsi") = (long)buf;
register long rdx asm("rdx") = count;
asm volatile(
"syscall"
: "+r"(rax)
: "r"(rdi), "r"(rsi), "r"(rdx)
: "rcx", "r11", "memory"
);
return rax;
}In my memory the syscall ABI has changed a few times (i386 had int $0x80, then sysenter, then abstracting it in the vdso, then amd64 has 'syscall'), so it may be easier to let the kernel header provide the mechanism.
Modern macro assemblera are fun
That entire point is moot here because the abstraction in this case is a massive ball of crap and it's used everywhere. So you never get the benefit you think you would for using a lower level language. That's why generally LLMs are best with python and even better with a "harness" (domain specific framework and language)