Live data from Hacker News

What I Learned Making My Own JIT Language

mikedrivendevelopment.com

11–20 of 120 posts

Re: What I Learned Making My Own JIT Language

#11
post #4

Sure, there are things that can be "poison pills" for performance, even in JITs. For example, another reason why my fib benchmark beats V8 is that V8 has to continually check if the fib function was redefined as a deoptimization check. I don't allow that in Vaiven, so I can produce faster code. Dart was designed to have fewer of these poison pills, for instance. Note to language designers: Reduce your language's pois…

I would be intrigued to see a modern attempt at a dynamic language like Python or Ruby, but with attention paid from day one to ensure that only very JIT-able constructs were used, and with an eye towards the language helping the user stick to those and be aware of when they deviate, rather than designing a language, setting "runs fast" somewhere around the third or fourth priority, then trying to JIT it after 10-15…

I guess you mean Julia, or to pick three from the past Common Lisp, Dylan and Strongtalk.

Re: What I Learned Making My Own JIT Language

#12
post #9

Earlier quoted context omitted.

Is there a list of common language poison pills? I'd like to learn more.

Well, I can't do a full list, but: Memory non-locality. On modern systems, thrashing through RAM just kills you on performance. I don't know that you have to hand full control over to the programmer, but if you're randomly flinging values on the heap everywhere (a.k.a. "hash tables"), you're gonna hit a wall long before you get to "C performance". For JITs, any time the JIT has the ability to make an assumption, but…

> I don't know that you have to hand full control over to the programmer, but if you're randomly flinging values on the heap everywhere (a.k.a. "hash tables"), you're gonna hit a wall long before you get to "C performance".

Rule of Python: Everything is at least two pointers away.

--

> and CPython is hopping through all these hoops for every such lookup.

Actually CPython has a cache for that. This becomes apparent if you improperly replace methods in the class dictionary.

I think the bane of Python specifically is a bit different. It's not so much that it's very dynamic, because JITs can clearly deal with that. It's that CPython exposes all kinds of interpreter state that's off-limits in other languages, which makes it way harder to JIT. In JavaScript there are at most a handful ways how you can mutate a prototype, but in CPython you don't have enough fingers to count them, even if you only consider Python and not the C API.

Re: What I Learned Making My Own JIT Language

#13

Sure, there are things that can be "poison pills" for performance, even in JITs. For example, another reason why my fib benchmark beats V8 is that V8 has to continually check if the fib function was redefined as a deoptimization check. I don't allow that in Vaiven, so I can produce faster code. Dart was designed to have fewer of these poison pills, for instance. Note to language designers: Reduce your language's pois…

Isn't there some kind of static analysis possible for such cases?

Re: What I Learned Making My Own JIT Language

#14
post #13

Sure, there are things that can be "poison pills" for performance, even in JITs. For example, another reason why my fib benchmark beats V8 is that V8 has to continually check if the fib function was redefined as a deoptimization check. I don't allow that in Vaiven, so I can produce faster code. Dart was designed to have fewer of these poison pills, for instance. Note to language designers: Reduce your language's pois…

Isn't there some kind of static analysis possible for such cases?

If you could perform static analysis on these cases, why couldn’t the JIT just do so itself and not have any issues?

Re: What I Learned Making My Own JIT Language

#15

Sure, there are things that can be "poison pills" for performance, even in JITs. For example, another reason why my fib benchmark beats V8 is that V8 has to continually check if the fib function was redefined as a deoptimization check. I don't allow that in Vaiven, so I can produce faster code. Dart was designed to have fewer of these poison pills, for instance. Note to language designers: Reduce your language's pois…

Is there a list of common language poison pills? I'd like to learn more.

Anything that has to be interpreted or un-JIT'd for the most part. Runtime eval, runtime struct memory layout redefining, runtime type change, etc. Basically it's a trade off between pre-compiled immutable omniscience and developer friendliness. Targeting the former often increases perf due to the assumptions you can make, targeting the latter increases comfort and adoption and usability and simplicity.

Re: What I Learned Making My Own JIT Language

#16
post #13

Earlier quoted context omitted.

Isn't there some kind of static analysis possible for such cases?

If you could perform static analysis on these cases, why couldn’t the JIT just do so itself and not have any issues?

Well, I suppose a JIT has tighter time constraints.

Re: What I Learned Making My Own JIT Language

#17
post #9

Earlier quoted context omitted.

Well, I can't do a full list, but: Memory non-locality. On modern systems, thrashing through RAM just kills you on performance. I don't know that you have to hand full control over to the programmer, but if you're randomly flinging values on the heap everywhere (a.k.a. "hash tables"), you're gonna hit a wall long before you get to "C performance". For JITs, any time the JIT has the ability to make an assumption, but…

> I don't know that you have to hand full control over to the programmer, but if you're randomly flinging values on the heap everywhere (a.k.a. "hash tables"), you're gonna hit a wall long before you get to "C performance". Rule of Python: Everything is at least two pointers away. -- > and CPython is hopping through all these hoops for every such lookup. Actually CPython has a cache for that. This becomes apparent if…

"Actually CPython has a cache for that."

My apologies for my unclarity. In my head, "hopping through all these hoops" included using caching, but that is completely unclear. It is true that there is a lot of caching being done, because it would simply be unusable if there isn't. But it is also true that there is still a lot of work to do for "x.y()", even when all caches are used fully.

Re: What I Learned Making My Own JIT Language

#18
post #13

Sure, there are things that can be "poison pills" for performance, even in JITs. For example, another reason why my fib benchmark beats V8 is that V8 has to continually check if the fib function was redefined as a deoptimization check. I don't allow that in Vaiven, so I can produce faster code. Dart was designed to have fewer of these poison pills, for instance. Note to language designers: Reduce your language's pois…

Isn't there some kind of static analysis possible for such cases?

JavaScript is too dynamic for such analysis. JavaScript at its core is not a very well designed language, and it's a bloody miracle that a JIT can make it usable.

If you're designing a new language, don't make everything (even arrays!) a hashmap.

Re: What I Learned Making My Own JIT Language

#19
post #17

Earlier quoted context omitted.

> I don't know that you have to hand full control over to the programmer, but if you're randomly flinging values on the heap everywhere (a.k.a. "hash tables"), you're gonna hit a wall long before you get to "C performance". Rule of Python: Everything is at least two pointers away. -- > and CPython is hopping through all these hoops for every such lookup. Actually CPython has a cache for that. This becomes apparent if…

"Actually CPython has a cache for that." My apologies for my unclarity. In my head, "hopping through all these hoops" included using caching, but that is completely unclear. It is true that there is a lot of caching being done, because it would simply be unusable if there isn't. But it is also true that there is still a lot of work to do for "x.y()", even when all caches are used fully.

Yes... and most of it is even part of stable APIs.

Re: What I Learned Making My Own JIT Language

#20
post #4

Sure, there are things that can be "poison pills" for performance, even in JITs. For example, another reason why my fib benchmark beats V8 is that V8 has to continually check if the fib function was redefined as a deoptimization check. I don't allow that in Vaiven, so I can produce faster code. Dart was designed to have fewer of these poison pills, for instance. Note to language designers: Reduce your language's pois…

I would be intrigued to see a modern attempt at a dynamic language like Python or Ruby, but with attention paid from day one to ensure that only very JIT-able constructs were used, and with an eye towards the language helping the user stick to those and be aware of when they deviate, rather than designing a language, setting "runs fast" somewhere around the third or fourth priority, then trying to JIT it after 10-15…

I know at least in LuaJIT you can use FFI to declare structs beforehand and gain a bunch of performance. But that's not a JIT-provided step. That's just something you have to do by hand.
Post reply on HN