5 ms·
There is a reason why basically every attempt to make this kind of language fast has to support some form of on-stack replacement. For example, it's hard to op
by obl 8y ago
There is a reason why basically every attempt to make this kind of language fast has to support some form of on-stack replacement.
For example, it's hard to optimize even local variable dataflow in python since it's part of the API : you can inspect the local frame of your caller, so you have a problem as soon as your function contains a single call. And no you can't know statically what is the call target since it can be replaced dynamically.
So either you perform the optimization anyway and then have to try to support reconstructing values correctly to support introspection, or you just do that generically with OSR and use the simple introspection on the interpeter.
Either way, there are not a lot of "simple optimization" when the language is so dynamic.
- sametmax 8y agoYou could support markers stating "I swear this part is never going to use those dynamic features", disabling them for you and others. E.G: I have no problem putting a few annotation telling Python I'm not going to and allow to override builtins in my program and it's dependancies. We could make sure those markers can only be set in __main__, and crashes with very explicit errors in the unlikely event anything down there decide to do otherwise. Indeed, many dynamic features are rarely used. They are handy from time to time, but I won't miss them for many codes.
- pishpash 8y agoHow can you know the builtins and the libraries you call don't use these features, to make such guarantees? I suspect it's rather more common than it appears.
- sametmax 8y agoYou can't at first, but you don't need to. You just write normal code, with regular unit tests. Once you are satisfy, you can start playing with optimization and see if things break or get faster. Things like monkey patching and stack inspection are the excetion rather than the rule. You may very well be able to safely disable many feature at some local level, or in prod but not dev, etc.
- coredog64 8y agoOne of the event workers for Django monkey patches ‘socket’. A colleague and I discovered that an hour into debugging why something was misbehaving when we switched workers.
- jerf 8y ago"You could support markers stating "I swear this part is never going to use those dynamic features", disabling them for you and others." Right now, the swing is in general to statically-typed languages that are more convenient to use, but I've thought there's room for a new dynamic scripting language that is still dynamically typed, but is written from the beginning to focus on speed. You can see some of the ideas in Julia or LuaJIT, but you pay a penalty on what can be dynamic. One of the ideas I've had is more like the "pledge" feature that OpenBSD recently introduced. Rather than stating up front "I will not use this feature", you initialize your program, do all the dynamic stuff, then push the "OK, now I'm done being dynamic" button. After that, the program "freezes" into place, and calling a function with a new type of argument it has never seen before or something becomes an error. My reasoning here is that the dynamic scripting languages tend not to use their dynamism evenly. The vast bulk of "dynamic" behavior is all done in an informal initialization phase, but then, for the bulk of the program's execution, you continue to pay for all the dynamism because the interpreter has to constantly follow the dynamic chains of functions, or even if the code is JIT'ed, the JIT has to be written to handle functions suddenly getting the "wrong" type, which at the very least means you pay for a check the static programs don't need to pay for, and generally, you may have to pay more. You set up the dynamism once at the start of the program, but pay for the ability to be dynamic later billions and trillions and so on of times over the course of the program. (Don't just think about how poorly this would work if bodged onto Python or Javascript or something, because I know such an attempt would absolutely be a disaster. That's why I'm hypothesizing someone sitting down and designing this language from scratch with these ideas in mind, so it'll have the correct affordances and paved cow paths and such to make this work. While you're at it, give your new dynamic scripting language a solid concurrency story, since none of the current ones have one, since they all grotesquely predate that as a concern. I think there's a hole in the programming language landscape here right now. Another way to think of this is "write a dynamic scripting language that is designed to have a good, simple JIT".) (Actually, for all the languages there are, I think there's several holes in the programming language landscape right now. You'd think everything would be covered, but it really isn't.)
- Sukera 8y ago> You can see some of the ideas in Julia or LuaJIT, but you pay a penalty on what can be dynamic. I'm sorry but I think I'm missing something here - what sort of penalty are you paying in terms of dynamicness? Can you be more specific?
- chrisseaton 8y ago> You could support markers stating "I swear this part is never going to use those dynamic features" You shouldn't have to! The VM should be able to work this all out for you. One person puts the effort into improving the VM rather than everyone has to work around in their program.
- pjmlp 8y agoYet Smalltalk, Common Lisp, Dylan managed to do it. Do you want to break all assumptions a Smalltalk JIT managed to reach about a live object? Just send it a become: message.
- masklinn 8y agoYeah the dynamicism part is probably not a good argument there (JITs were built for Self, after all). It's really a combination of dynamicism and desire for approachability of the codebase: the cpython codebase is not beautiful, but it's definitely approachable, there is very little use of tricks or complex macros and the average Python developer can jump around and find things.
- mschaef 8y ago> For example, it's hard to optimize even local variable dataflow in python since it's part of the API : you can inspect the local frame of your caller, This seems like the sort of thing that should be absolutely not relied upon outside of debugging/profiling and other special circumstances. At least in my experience, I've had to write this sort of thing a few times and it's always been a last resort (and mainly for those purposes I mentioned). Not only is it problematic because it disallows compiler optimizations, it also seems like it would enforce an unchangable set of local vars.