From: Sean Middleditch Date: 2002-04-05T00:41:59+09:00 Subject: Re: About efficiency On Thu, 2002-04-04 at 01:27, nobu.nokada@softhome.net wrote: > Hi, > > At Wed, 3 Apr 2002 10:46:24 +0900, > Sean Middleditch wrote: > > Hmm, how would that work with loadable modules? Either you'd have to > > store a lot of meta information, or modules that try to access a > > variable in the wrong way from another module would cause a crash or > > some other bad side-effect. > > I guess it's so hard. ^,^ That's how I look at it. > > > > > You know, one cache I found useful in Scriptix (dunno if Ruby uses it) > > is a name cache. I.e., if you have a small loop that references the > > same small number of variables/members/etc., the code has a string to > > find the name against. Well, comparing pointers is faster than > > comparing a whole string. So, the compiler caches the last 20 (or > > whatever number) names is encountered, so the byte-code (or node tree) > > can just have multiple copies of the same string in memory. This > > reduces memory usage for variable name lookups, plus makes the lookups > > faster by reducing the complexity of the name comparisons. This > > optimization had a nice effect in Scriptix, so if Ruby doesn't use it > > now, it might make a big difference if it did. > > In ruby, identifiers are handled as numeric ID commonly. Don't > you mean this? Sort of - are the names converted to ID's at compile time or run-time? > > Hmm. if you stored them all in a dynamically allocated array, that > > might make it work (only appending entries). The problem I see is > > getting the interpreter to know what to cache when. Doing it at run > > time would just add over-head to the current member search, wouldn't > > it? (Maybe I'm just not seeing how this optimization works.) > > Adding instance variables dynamically means that it's > impossible to predict the order of them. I guess it needs to > map ID to index finally. Well, with a cache, you wouldn't need to know the order until first encountered. If you don't allow the removal or deletion of members, then once cached, the index will always be valid. > > That's something I've been toying with. A powerful optimizer can make > > the runtime code a *lot* faster, but significantly slow down the > > compiler. If you load a script once and let it run for a very long time > > (i.e., a full-scale application, or large mathematical computations), or > > if you run a small script repeatedly (using scripts as callbacks in > > triggers in an embedding application), then the greatly increased > > compile time could well be worth it. > > No doubt that inlining will make code faster much, if no method > redefinition. But it may be difficult to reduce drawback on > the redefinition. Perhaps if we had a way of marking a method as "constant" or "static" ? Then the compiler would know that the value cannot change, and it can inline to its heart's content. > > > I've not looked much at the Ruby compiler, but perhaps two separate > > compilers would be possible? A simpler, lighter one that compiles > > quickly and runs at moderate speed, and a complex one that may take many > > seconds to compile a smaller app/script, but run at lightning speeds? > > > > Also, a more complex compiler may be useful if Ruby let you save to some > > form of bytecode (hell, even an binary or XML representation of the > > current node tree scheme), then load that back in. You could do like > > you would with C - spend a lot of time compiling, but get applications > > much much faster than a fully interpreted language. > > IMHO, bytecode serialization may be a prerequisite to optimize > more, a more complex compiler. But I'm afraid about the > drawback. Which drawback? > > -- > Nobu Nakada