Process consists of a number of phases. Each phase provides a feedback on its performance.
Instead of defining some performance threshold for each phase to start optimization at and asking ourselves “when should we start optimizing this?”, we should rather ask ourselves “which phase is to be optimized now?”. That is, we should collect all feedback, sort it and start optimizing most important phases first. Naturally, we end the process when we are not getting any visible performance gains anymore.
This strategy can be applied to dynamic programming language runtime as well as to any other controllable process.
At each callsite (source code point, where method dispatch happens) we can count
1) number of calls to a method
2) time spent inside the method
3) time spent in callsite (total time across all methods called at the point).
Time can be measured either in byte code instructions, machine instructions or in microseconds.
Lets look at possible situations:
In real code, we don’t meet frequently called very slow methods: it is often done by bad design and could not be efficiently optimized in runtime. But this chart helps us to define a metric for “hot spot” identification: the place in the code, where we start runtime optimization.
Such “hotspot” metric would be callsite time * number of calls. The higher this number, the higher priority should be given to such callsite at optimization phase.
Why don’t we just start with a top-level method? If we start from the very top, we would spend enormous amount of time optimizing the whole program instead of really interesting parts.
Now i can easily bring my favorite aliases and commands to different environments: macbooks, linux and freebsd servers.
Ruby symbols should be just immutable strings to avoid all that mess with string/symbol keys in option hashes. Just treat every literal string as immutable one. You could even keep this nice syntax with a colon to save some keystrokes.
So, basically:
String.should < ImmutableString
“symbol”.should == :symbol
Parser still fills a table of symbol when it encounters literal strings in the source code. So the unique number is just a string object_id.
When you compare two strings, you compare ids first and if they are not the same, you proceed with byte comparison. No need to convert :symbol.to_s.
How to make string a mutable one? Just #dup or #clone it.
“symbol”.dup.class.should == String