From: nobu.nokada@... Date: 2002-04-04T15:27:59+09:00 Subject: Re: About efficiency Hi, At Wed, 3 Apr 2002 10:46:24 +0900, Sean Middleditch wrote: > > > 3) type induction (snip) > > It's been discussed some times, but not implemented yet. > > 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. > > > 4) String (snip) > > Shugo Maeda had made a patch, but it's left yet due to the > > impact on the external interface mainly. > > Wow, that's a nice one. Will have to try that in Scriptix and see what > kind of performance and memory gain I can get (I'm more interested in > performance - less memory allocations is nice for that.) > > > 5) Cache. (snip) > > Method cache is implemented already. > > 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? > > You can add instance variables on the fly, the last assumption > > may not be correct. I considered it too, but had no good idea. > > 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. > > > A less trivial cache is for inlining small methods. This > > > is specially efficient for accessors. I think it is described > > > too in the books about the implementation of Smalltalk > > > 80. > > > > Maybe, but it may prohibit/restrict forward reference, or gain > > compile time cost much. > > 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. > 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. -- Nobu Nakada