6 ms·
The Green Side of the Lua
- Rochus 5mo agoInteresting results. Particularly they barely found a speed-up of newer compared to older LuaJIT versions (rather the contrary). Maybe they should have used the Are-we-fast-yet suite instead of the (random looking) set of microbenchmarks. I did measurements of Lua and LuaJIT some time ago based on Are-we-fast-yet and saw significant differences in LuaJIT performance (see http://software.rochus-keller.ch/are-we-fast-yet_LuaJIT_2017_vs_2023_results.pdf http://software.rochus-keller.ch/are-we-fast-yet_LuaJIT_2017...). I also compared different PUC Lua versions in an earlier measurement (see http://software.rochus-keller.ch/are-we-fast-yet_lua_results_2020-10-12.pdf http://software.rochus-keller.ch/are-we-fast-yet_lua_results...) and found similar significant differences between versions.
- Rochus 4mo agoHere is the repository with the benchmarks: https://github.com/rochus-keller/are-we-fast-yet/ https://github.com/rochus-keller/are-we-fast-yet/ And here is a repository with a compiler backend to generate LuaJIT bytecode and other useful tools: https://github.com/rochus-keller/ljtools/ https://github.com/rochus-keller/ljtools/
- NuclearPM 4mo agoI am currently implementing a personal programming language on top of luajit. Have you found that generating bytecode is actually faster (compile time and more importantly runtime) than just generating Lua (like Moonscript and Fennel does)?
- Rochus 4mo agoCool. It's still a great backend, even for a statically typed language, and the FFI and debugger features are very useful. Mono is yet another great backend which in addition supports multiple threads and has the higher performance, but with a (slightly) higher footprint. I have used both in different projects (see e.g. https://github.com/rochus-keller/Oberon https://github.com/rochus-keller/Oberon or https://github.com/rochus-keller/Luon https://github.com/rochus-keller/Luon), and currently I'm even implementing a LuaJIT bytecode generator for my Micron intermediate language which uses LuaJIT essentially as a kind of C interpreter, even with my own native stack and GC (https://github.com/rochus-keller/Micron https://github.com/rochus-keller/Micron). The reason why I switched from generating Lua source code to LuaJIT bytecode in 2019 was mostly the higher flexibility. I could better avoid operations not yet supported by the tracer, and some language features of Oberon+ didn't match well to Lua. And adding line information for debugging was much easier. And it was a fun project and the bytecode was well documented. It's certainly also a bit faster, but I haven't done specific measurements.
- NuclearPM 4mo agoThanks again for this. My goals are: Deep copy value passing semantics by default (with outs for hotpath and some optimization). Persistence by default using SQLite. (Again, opt out for hot paths). Lua tables, but callable. Also every object is a continuation. Optimizations for js are float64 arrays with the 0 index holding some meta stuff - but semantically just objects and messages. No variables, just fields. Fields can be thought of as canned message responses. Fallthrough is “call”.
- Rochus 4mo agoWhen you consider SQLite, you might want to get around SQL for impedance and performance reasons. There is a robust and decently fast key/value store in the backend. I used it in some of my projects (e.g. https://github.com/rochus-keller/udb https://github.com/rochus-keller/udb used e.g. in https://github.com/rochus-keller/crossline/ https://github.com/rochus-keller/crossline/). Depending on read/write frequency, lmdb or tidesdb might be a better fit.
- NuclearPM 4mo agoThis is cool. I wonder if WASM would work here as a target for the k/v store.
- NuclearPM 4mo agoIs V8 faster than Luajit now? That is surprising to me.
- Rochus 4mo agoV8 was significantly faster than LuaJIT when I did measurements in 2021 (see https://github.com/rochus-keller/Oberon/blob/master/testcases/Are-we-fast-yet/Are-we-fast-yet_results_linux.pdf https://github.com/rochus-keller/Oberon/blob/master/testcase..., didn't measure it since). Sure there are microbenchmarks where LuaJIT performs equally well or even faster, but overall (geomean of factors) V8 was 2.5 times faster. This comes with a price though. If you're interested in performance, Mono was equally fast as V8 in my measurements but much leaner, and more flexible with a well-documented bytecode, or use a LuaJIT or Mono backend for the development environment and offer a C transpiler for maximum performance at runtime.
- NuclearPM 4mo agoThank you. I am planning to argent Lua and Js(browser), and my (very much LLM assisted) demo already is with x2 range of js. I guess in my head, I really liked the idea of the simplicity and size of Lua/luajit - but maybe for people like me, who have no hope of designing competitive JITs, the future is just to spit out JavaScript. Your work has been an inspiration to me for quite a long time but the way.
- Rochus 4mo agoThanks, great that the work is useful.
- aa-jv 4mo agoAs someone who has shipped Lua as a solution to many an embedded dilemma, this is highly interesting work. I wonder if there will be motivation in the future to address energy consumption in future JIT work .. in fact I wonder whether other languages are going to face a similar optimization path. It would be grand to see progress being made on this at a more general scale. I'm looking at you, Python ..
- PaulRobinson 4mo agoEnergy efficiency as a "my language is better than yours" point was not on my bingo card for 2026. JIT as an energy saver intuitively makes sense, and is probably the model most languages need to think about for "shipping to prod". I'm aware Python has started developing this, and given the install base, it's encouraging that results like this show it could have significant benefits for users.
- vaylian 4mo agoThe nice thing about Lua is that it can easily be combined with compiled languages. If you identify the hot path in your program, you can implement them in a more efficient language.
- themafia 4mo agoThe C interface to ruby is just superb. It provides a very simple and first class access to the entire runtime and all it's features. It's absolutely my favorite language to write extensions in. Lua is probably my second favorite. It's marred by it's initial creation as a stack based interpreter and requires more calls and contortions to achieve the same effects as you would in any other language; however, once you understand a handful of useful primitives it's quite easy to intuit the correct set of calls for any use case. The blend of dynamic language with underlying compiled extensions is vastly underappreciated. I suspect it has a lot to do with the difficulty of packaging and distributing these extensions into current virtualized and cloud environments. Which is a pity given the extreme combination of flexibility and efficiency that it otherwise unlocks.
- pansa2 4mo ago> The C interface to ruby is just superb. How does it handle garbage collection? AFAIK GC is the main reason behind Lua's stack-based API: it's designed so that C code never needs to hold a pointer to a Lua object, which means an object will never be garbage-collected while C code is still trying to use it. OTOH Python does allow C code to hold such pointers - so it requires that code to perform error-prone manual reference-counting. How does Ruby solve this problem?
- themafia 4mo ago> How does Ruby solve this problem? The interpreter keeps track of globals and all stack frames. So it knows what objects are in scope. If you're creating an object that can contain native ruby values inside it's own opaque structure, then when you define the class that wraps this structure you reference the callback functions you want to be called during GC mark and when the GC frees your object. During the mark callback you simply call rb_gc_mark on any of those internal values so the GC knows they are in scope. In practice it's quite easy to use and you can find many examples of this. There is no equivalent I'm aware of to mark in lua, but the free callback is effectively equivalent to the __gc metamethod.
- fouronnes3 4mo agoIs a paper that publishes a 0.01% improvement of something at the cost of 5 times more power really an improvement? I believe that every single computer science measurement metric should have Joules or Watts in the denominator. If you are training a model I want to see performance per total energy consumed. If you are measuring inference accuracy, measure PER WATT. I've always been a bit confused by the apparent tendency of the computer science field to mostly ignore energy and power. We are too often satisfied with the idea that software and programs exist in a perfect whiteboard world of xkcd 505 abstract compute.
- tancop 4mo agoopen source ai labs care a lot about inference speed. that translates to energy and e waste (gpus that work for less time take longer to wear out). training power is another thing and thats where we see a lot of duplicate work we could fix by making it mandatory to release weights for all models above some total power limit. if you want to look at the real waste of power just open up some electron app. no good reason why we still use it for new apps in 2026 when gpui and avalonia and tauri are all options
- Imustaskforhelp 4mo agoGPUI is still very hard to build things upon the last time (from my limited experimentation) I checked but I wish the team @Zed luck for the GPUI project as I am definitely fascinated by it and its certainly an interesting project for sure!
- perilunar 4mo agoSave a few watts per device making the client-side code a bit more efficient. Spend Gigawatts running data centres for LLMs.
- keybored 4mo agoMost environmental chatter in a nutshell.
- indy 4mo agoShare this article on LinkedIn and you'll have countless managers talking about how they initiated a company wide policy to convert all Python scripts into Lua using Claude
- keybored 4mo agoAs Earth stakeholders, saving watts is not just good business sense—it’s a Kantian imperative.
- hawkice 4mo agoIsn't this a Goomba fallacy? The people trying to conserve energy and the people who are using vastly more energy than before are different individuals, no singular person is contradicting their values.
- benj111 4mo agoI'd label it as more related to Jevon's paradox. They arent saying they're the same individual. Just that this is very quickly undone by other developments. But anyway it'll devolves pretty quickly into a fallacy where you shouldn't do anything because your neighbour is a bigger problem (forget the name).
- deleted 4mo ago[deleted]
- RetroTechie 4mo ago1) Power saved scales with # of devices. Even modest savings can have a massive effect if it's software that runs on billions of devices. 2) There exist many, many more client devices than datacenters. And 3) Expect software on client devices to be generally less optimized than software deployed in datacenters. In other words: measure, and do the math. And ofc Jevons' paradox may apply.
- winter_blue 4mo agoI'd like to see a study that compares Python and Ruby, against (1) Rust, (2) C, (3) C++, (4) Zig, (5) Go, (6) a JVM language (like Scala or Kotlin or Clojure), and (7) the main CLR language (C#). I would imagine that all 7 of them absolutely trounce Python and Ruby. Python and Ruby have been an immense environmental (and type safety) disaster. JS though (via V8 and other engines) has been surprisingly fast. I've always wondered why Python and others couldn't copy some of the tricks V8 uses to be fast...
- dbdr 4mo agoEnergy Efficiency across Programming Languages: How Does Energy, Time, and Memory Relate? https://greenlab.di.uminho.pt/wp-content/uploads/2017/09/paperSLE.pdf https://greenlab.di.uminho.pt/wp-content/uploads/2017/09/pap...
- TeriyakiBomb 4mo agoI think it’s a question of investment. Google had incentive to pour tons of cash into V8. In recent years Shopify have been more involved with Ruby directly with yjit and zjit. The former bringing a pretty substantial performance improvements to the language.
- faangguyindia 4mo agoYou won't realize but modern ruby is fast. Faster than python.
- ianm218 4mo ago> Python and Ruby have been an immense environmental (and type safety) disaster. The vast majority of code is not performance bottleknecked at the language level. I.e. Instagram still runs on an optimized version of Django as far as I know. For most Web companies most of the optimization is at the query/ db/ storage/ network level.
- lucascdotnet 4mo agoIs the title "The Green Side of the Lua" a pun/parodic allusion to something? I have been compiling a list of papers that have titles with this kind of style.
- pansa2 4mo agoI guess it alludes to “The Dark Side of the Moon”
- keybored 4mo ago“Lua” is “moon” in Portuguese, so it’s a reference to Dark Side of the Moon.
- lucascdotnet 4mo agoAh - wonderful. Thanks
- helenite 4mo agoHave you published the list yet?
- lucascdotnet 4mo agoNot yet, I will update you when I do.
- morgoths_bane 4mo agoO lado verde da Moon.
- misja111 4mo agoThis kind of article keeps coming back, I've seen similar articles on LinkedIn where the bottom line is to switch from Python to C. The reasoning, in a nutshell, is that if a language allows you to waste fewer CPU cycles, it is more energy efficient, hence greener. This completely ignores the fact that such a language might be more difficult to master because it uses fewer higher abstractions; CPU efficient languages tend to be closer to the machine domain and further away from the mathematical and real world. So while in theory the language lets you write very efficient code, you might well miss the opportunity and it could even be that using some off the shelve abstraction in a higher level language, your code would have been more efficient. To drive that point to the extreme: the ultimate CPU efficient language is the language of the CPU itself: assembly. Try writing an efficient highly scalable webserver in assembly alone, good luck with that. Then there is something else that all these articles conveniently ignore: development speed. Most of us write software for commercial enterprises. Product owners want the new feature tomorrow, not next year. They don't want a clever and amazingly fast application that might crash in production, they don't want security holes by missed buffer overflows. Also, most of us work in a team where colleagues come and go, including yourself. Your colleagues won't be happy with you when you leave them some amazingly cleverly and efficiently written software that nobody understands or can maintain. TL;DR; while all else being equal, the point of the article is true: it has little to no meaning in the real world. Yet, with phrasing like 'green languages', 'reduce the carbon footprint', these articles will catch on to an uninformed audience again and again.
- dbdr 4mo agoThis paper is relevant: Energy Efficiency across Programming Languages: How Does Energy, Time, and Memory Relate? https://greenlab.di.uminho.pt/wp-content/uploads/2017/09/paperSLE.pdf https://greenlab.di.uminho.pt/wp-content/uploads/2017/09/pap... This is the main summary table: Energy Time Memory (c) C 1.00 (c) C 1.00 (c) Pascal 1.00 (c) Rust 1.03 (c) Rust 1.04 (c) Go 1.05 (c) C++ 1.34 (c) C++ 1.56 (c) C 1.17 (c) Ada 1.70 (c) Ada 1.85 (c) Fortran 1.24 (v) Java 1.98 (v) Java 1.89 (c) C++ 1.34 (c) Pascal 2.14 (c) Chapel 2.14 (c) Ada 1.47 (c) Chapel 2.18 (c) Go 2.83 (c) Rust 1.54 (v) Lisp 2.27 (c) Pascal 3.02 (v) Lisp 1.92 (c) Ocaml 2.40 (c) Ocaml 3.09 (c) Haskell 2.45 (c) Fortran 2.52 (v) C# 3.14 (i) PHP 2.57 (c) Swift 2.79 (v) Lisp 3.40 (c) Swift 2.71 (c) Haskell 3.10 (c) Haskell 3.55 (i) Python 2.80 (v) C# 3.14 (c) Swift 4.20 (c) Ocaml 2.82 (c) Go 3.23 (c) Fortran 4.20 (v) C# 2.85 (i) Dart 3.83 (v) F# 6.30 (i) Hack 3.34 (v) F# 4.13 (i) JavaScript 6.52 (v) Racket 3.52 (i) JavaScript 4.45 (i) Dart 6.67 (i) Ruby 3.97 (v) Racket 7.91 (v) Racket 11.27 (c) Chapel 4.00 (i) TypeScript 21.50 (i) Hack 26.99 (v) F# 4.25 (i) Hack 24.02 (i) PHP 27.64 (i) JavaScript 4.59 (i) PHP 29.30 (v) Erlang 36.71 (i) TypeScript 4.69 (v) Erlang 42.23 (i) Jruby 43.44 (v) Java 6.01 (i) Lua 45.98 (i) TypeScript 46.20 (i) Perl 6.62 (i) Jruby 46.54 (i) Ruby 59.34 (i) Lua 6.72 (i) Ruby 69.91 (i) Perl 65.79 (v) Erlang 7.20 (i) Python 75.88 (i) Python 71.90 (i) Dart 8.64 (i) Perl 79.58 (i) Lua 82.91 (i) Jruby 19.84
- flossly 4mo agoWhen I read this I can help but feel the energy inefficiency of the self-admitted [1] "billion dollar mistake" that was adding implicit nulls to the C language (and thereafter many other languages). A bit broader: I wonder how strong typing can save energy! Maybe it makes compiling more energy consuming, but a bug in production costs a lot more energy than a few extra rounds of compiling. Very hard to get data on. But would totally change the ranking of proglangs by "efficiency".
- keyle 4mo agoExactly. You've expressed what I couldn't find the words to say. I love C, but the shear amount of CVE and crashes are much worse in terms of global energy usage than if it were safe. I imagine the strongest strong-typing ranking that can be saved would come from Swift, where Rust's compile time would tank its ranking...
- flossly 4mo agoIt may be that the energy drain of bugs simply eclipses the compile/run overhead of all these languages in nearly all use cases.
- ianm218 4mo agoI happened to just build a Rust port of Lua this past week [1] for 5.4.7 have been diving back into this world for the first time in a long time. There is some free lunch on performance compared to the C implementation on tables, but the rest is quite hard to get down to parity. Especially if you are trying to make the Rust code highly safe. My goal in the longer run is to support Lua 5.5, 5.1 and then eventually LuaJIT fully in Rust. I'm starting working with some folks in the game dev space but hoping to also make it easy to support Lua in Redis/ Valkey like applications in Rust without bundling C (which will need 5.1 and LuaJit). [1] https://github.com/ianm199/lua-rs/tree/main https://github.com/ianm199/lua-rs/tree/main [2] https://ianm199.github.io/lua-rs/harness/bench/history/index.html https://ianm199.github.io/lua-rs/harness/bench/history/index...