Ruby loaded file vs eval
-
For a long time I've been wondering how the Kernel.load works. When ruby file is being loaded I assume all the content in the file is converted to C and then into asdgfdg34234798cxvxcblablabla commands that the computer can interpret.
So, assuming it works the way I described above then writing a method one time and calling it multiple times will work much faster than evaluating the content of the method multiple times because calling the method won't require interpreting the code each time:
Example: (A piece of code from my tool)
<span class="syntaxdefault">def doOnMouseMove1</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">x</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">y</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> puts </span><span class="syntaxstring">'mouse moved'<br /></span><span class="syntaxdefault"> area </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">(</span><span class="syntaxdefault">x</span><span class="syntaxkeyword">**</span><span class="syntaxdefault">2</span><span class="syntaxkeyword">+</span><span class="syntaxdefault">y</span><span class="syntaxkeyword">**</span><span class="syntaxdefault">2</span><span class="syntaxkeyword">)**</span><span class="syntaxdefault">0.5<br /> puts </span><span class="syntaxstring">"Area; #{area} pixels squared"<br /></span><span class="syntaxdefault">end<br /><br />def doOnMouseMove2<br /> code </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">%</span><span class="syntaxdefault">q</span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">puts </span><span class="syntaxstring">'mouse moved'<br /></span><span class="syntaxdefault">area </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">(</span><span class="syntaxdefault">x</span><span class="syntaxkeyword">**</span><span class="syntaxdefault">2</span><span class="syntaxkeyword">+</span><span class="syntaxdefault">y</span><span class="syntaxkeyword">**</span><span class="syntaxdefault">2</span><span class="syntaxkeyword">)**</span><span class="syntaxdefault">0.5<br />puts </span><span class="syntaxstring">"Area; #{area} pixels squared"<br /></span><span class="syntaxkeyword">}<br />eval(</span><span class="syntaxdefault">code</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">end<br /><br />def onMouseMove</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">flags</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> x</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> y</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> view</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment"># Which one will be faster? calling doOnMouseMove1 or doOnMouseMove2<br /></span><span class="syntaxdefault"> doOnMouseMove1 <br />end</span>
I think the doOnMouseMove1 will work faster because it was already interpreted into machine commands when the file was loaded.
What bugs me is the way SketchyPhysics works. Each frame it evaluates the piece of code in the string mode. I just thought that it probably wastes time by interpreting a piece of code each frame.
I just don't know how the whole load thing works. I would like some clarification how the eval and the loading process works and whether my assumption is correct? I'm sorry if my question isn't that clear, but I hope it is understood.
Any answer, thought, fact, or url will be helpfull
Thank You
-
Yes, you have it right. A method definition is turned into 'byte-code' at definition time, and then just called, whereas 'eval' has to invoke the parser and work through the string every single time.
The 'eval' way can sometimes be handy for making 'dynamic' code, where the method definition is changed in 'real-time' according to the circumstances - but doing it every frame does seem very wasteful. Similar things can often be achieved using more efficient methods, such as building a lookup table of 'Proc' objects; but without knowing what the SP code is doing, it's hard to say if that option would be viable.
-
And anything that involves strings will be slow.
If you wonder about performance differences, run some timing tests and see. That's the only definite answer. Sometimes Ruby surprises you.
-
Thanks Trogluddite, your great explanation and mentioning Bytecode makes everything clear now. So, if I will start writing my own SketchyPhysics, for the best performace I will have to use methods and not evaluating blocks.
ThomThom, running timing tests is a great idea, but I expect many random results, especially if different processes change the system's performance.
-
Sure, but if the results are that close then it's insignificant. Large differences - the ones that matter you'll see quickly.
Advertisement