What is tail-recursion elimination? - language-agnostic
Steve Yegge mentioned it in a blog post and I have no idea what it means, could someone fill me in?
Is it the same thing as tail call optimization?
Tail call elimination is an optimization that saves stack space. It replaces a function call with a goto. Tail recursion elimination is the same thing, but with the added constraint that the function is calling itself.
Basically, if the very last thing a function A does is return A(params...) then you can eliminate the allocation of a stack frame and instead set the appropriate registers and jump directly into the body of the function.
Consider an (imaginary) calling convention that passes all parameters on the stack and returns the value in some register.
Some function could compile down to (in an imaginary assembly language):
function:
//Reading params B, C, & D off the stack
pop B
pop C
pop D
//Do something meaningful, including a base case return
...
//Pass new values for B, C, & D to a new invocation of function on the stack
push D*
push C*
push B*
call function
ret
Whatever the above actually does, it takes up a whole new stack frame for each call to function. However, since nothing occurs after the tail call to function except a return we can safely optimize that case away.
Resulting in:
function:
//Reading params B, C, & D off the stack (but only on the first call)
pop B
pop C
pop D
function_tail_optimized:
//Do something meaningful, including a base case return
...
//Instead of a new stack frame, load the new values directly into the registers
load B, B*
load C, C*
load D, D*
//Don't call, instead jump directly back into the function
jump function_tail_optimized
The end result is an equivalent function that saves a lot of stack space, especially for inputs that result in a large number of recursive calls.
There's a lot of imagination required in my answer, but I think you can get the idea.
from here:
"...Tail recursion elimination is a
special case of tail call elimination
in which the tail call is a call to
the function itself. In that case the
call can be replaced by a jump to the
start of the function after moving the
new arguments to the appropriate
registers or stack locations..."
from Wikipedia:
"...When a function is called, the computer must "remember" the place it was called from, the return address, so that it can return to that location with the result once the call is complete. Typically, this information is saved on the stack, a simple list of return locations in order of the times that the call locations they describe were reached. Sometimes, the last thing that a function does after completing all other operations is to simply call a function, possibly itself, and return its result. With tail recursion, there is no need to remember the place we are calling from — instead, we can leave the stack alone, and the newly called function will return its result directly to the original caller. Converting a call to a branch or jump in such a case is called a tail call optimization. Note that the tail call doesn't have to appear lexically after all other statements in the source code; it is only important that its result be immediately returned, since the calling function will never get a chance to do anything after the call if the optimization is performed...."
Related
What is the memory allocation when you return a function in Golang?
Here is a simplified code func MyHandler(a int) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteCode(a) }) } Whenever a http request comes MyHandler will be called, and it will return a function which will be used to handle the request. So whenever a http request comes a new function object will be created. Function is taken as the first class in Go. I'm trying to understand what actually happened when you return a function from memory's perspective. When you return a value, for example an integer, it will occupy 4 bytes in stack. So how about return a function and lots of things inside the function body? Is it an efficient way to do so? What's shortcomings?
If you're not used to closures, they may seem a bit magic. They are, however, easy to implement in compilers: The compiler finds any variables that must be captured by the closure. It puts them into a working area that will be allocated and remain allocated as long as the closure itself exists. The compiler then generates the inner function with a secret extra parameter, or some other runtime trickery,1 such that calling the function activates the closure. Because the returned function accesses its closure variables through the compile-time arrangement, there's nothing special needed. And since Go is a garbage-collected language, there's nothing else needed either: the pointer to the closure keeps the closure data alive until the pointer is gone because the function cannot be called any more, at which point the closure data evaporates (well, at the next GC). 1GCC sometimes uses trampolines to do this for C, where trampolines are executable code generated at runtime. The executable code may set a register or pass an extra parameter or some such. This can be expensive since something treated as data at runtime (generated code) must be turned into executable code at runtime (possibly requiring a system call and potentially requiring that some supervisory code "vet" the resulting runtime code). Go does not need any of this because the language was defined with closures in mind, so implementors don't, er, "close off" any easy ways to make this all work. Some runtime ABIs are defined with closures in mind as well, e.g., register r1 is reserved as the closure-variables pointer in all pointer-to-function types, or some such.
Actual function size is irrelevant. When you return a function like this, memory will be allocated for the closure, that is, any variables in the scope that the function uses. In this case, a pointer will be returned containing the address of the function and a pointer to the closure, which will contain a reference to the variable a.
Do locally declared lua functions get parsed every time they are passed?
Let's say I have a locally declared function inside another function that gets called a lot: function outer() -- Do stuff local loop = true while loop do -- for some reason local function inner() -- Do function stuff end -- Doing stuff inner() end end Does the inner function get newly created, parsed, processed, everything, every time it gets encountered at runtime? Basically, is there any performance difference between this pattern and declaring a separate standalone function? function inner() -- Do stuff end functions outer() local loop = true while loop do inner() end end
Short answer: No. When you run a Lua chunk (a chunk is usually a file, but sometimes a string), the entire chunk is compiled to bytecode before it is executed. When you define a local function, you are assigning a reference to that function's bytecode to the function's name. Lua does not re-evaluate the function itself. In your first code snippet, you might get a tiny performance penalty from assigning the bytecode reference to the local variable. Of course, you should benchmark that to be sure. I don't know if Lua can optimize that away. Note that closures can have different sets of upvalues, but still refer to the same function bytecode.
In addition to the answer that luther has provided, there is a bit more to this, but you can wonder if it is significant. I don't think it will matter a lot in performance. Lua will compile each function block, however when you use a local function it will have to execute the CLOSURE instruction and a MOVE instruction each time that particular code is called. The MOVE is added to prevent the CALL instruction from popping the closure off the stack. I don't believe Lua optimizes that bit in any case. If you have a global function or an upvalue, it will only need to acquire that value with an GETGLOBAL, GETTABUP or GETUPVALUE instruction. You can see the generated bytecode here; https://luac.nl/s/473abd2a0bb427a31766ea917
What is the effect of using JMP on a function address?
I was looking at a program in IDA as i was trying to figure out how a certain function worked, when I came across something like this: ; C_TestClass::Foo(void) __text:00000000 __ZN14C_TestClass7FooEv proc near __text:00000000 jmp __ZN14C_TestClass20Barr ; C_TestClass::Barr(void) __text:00000000 __ZN14C_TestClass7FooEv endp __text:00000000 Can anyone explain to me what exactly jumping to a function would do in a case like this? I am guessing that it acts as a wrapper for the other function?
You are correct that jumping is often a way to efficiently handle wrapper functions that aren't inlined. Normally, you'd have to read all the function parameters and push them back onto the stack before you can call the sub-function. But when the wrapper function has the exact same prototype: Same calling convention Same parameters (and in the same order) Same return type there's no need for all the usual function calling overhead. You can just jump directly to the target. (These categories may not be entirely necessary, as it may still be possible in some other cases.) All the parameters (either on the stack or register) that were setup when calling the wrapper function will already be in place (and compatible) for the sub-function.
This is what's known as a tail-call. The compiler is able to invoke the function directly and let it return to the original caller without causing any problems. For example: int f(int x) { ... return g(y); } The compiler can simply jmp g at the end because there is room for the arguments in the same place as f's arguments and the return value is not modified before returning to f's caller.
'Invalid Handle object' when using a timer inside a function in MatLab
I am using a script in MatLab that works perfectly fine by itself, but I need to make a function out of it. The script read a .csv file, extract all values, start a timer, and at each tick displays the corresponding coordinates extracted from the .csv, resulting in a 3D animation of my graph. What I would like is to give it the location of the .csv, so that it starts displaying the graphs for this csv. Here is what I have come up with: function handFig(fileLoc) csv=csvread(fileLoc,1,0); both = csv(:,2:19); ax=axes; set(ax,'NextPlot','replacechildren'); Dt=0.1; %sampling period in secs k=1; hp1=text(both(k,1),both(k,2),both(k,3),'thumb'); %get handle to dot object hold on; hp2=text(both(k,4),both(k,5),both(k,6),'index'); hp3=text(both(k,7),both(k,8),both(k,9),'middle'); hp4=text(both(k,10),both(k,11),both(k,12),'ring'); hp5=text(both(k,13),both(k,14),both(k,15),'pinky'); hp6=text(both(k,16),both(k,17),both(k,18),'HAND'); L1=plot3([both(k,1),both(k,16)],[both(k,2),both(k,17)],[both(k,3),both(k,18)]); L2=plot3([both(k,4),both(k,16)],[both(k,5),both(k,17)],[both(k,6),both(k,18)]); L3=plot3([both(k,7),both(k,16)],[both(k,8),both(k,17)],[both(k,9),both(k,18)]); L4=plot3([both(k,10),both(k,16)],[both(k,11),both(k,17)],[both(k,12),both(k,18)]); L5=plot3([both(k,13),both(k,16)],[both(k,14),both(k,17)],[both(k,15),both(k,18)]); hold off; t1=timer('TimerFcn','k=doPlot(hp1,hp2,hp3,hp4,hp5,hp6,L1,L2,L3,L4,L5,both,t1,k)','Period', Dt,'ExecutionMode','fixedRate'); start(t1); end And the doplot function used: function k=doPlot(hp1,hp2,hp3,hp4,hp5,hp6,L1,L2,L3,L4,L5,pos,t1,k) k=k+1; if k<5000%length(pos) set(hp1,'pos',[pos(k,1),pos(k,2),pos(k,3)]); axis([0 255 0 255 0 255]); set(hp2,'pos',[pos(k,4),pos(k,5),pos(k,6)]); set(hp3,'pos',[pos(k,7),pos(k,8),pos(k,9)]); set(hp4,'pos',[pos(k,10),pos(k,11),pos(k,12)]); set(hp5,'pos',[pos(k,13),pos(k,14),pos(k,15)]); set(hp6,'pos',[pos(k,16),pos(k,17),pos(k,18)]); set(L1,'XData',[pos(k,1),pos(k,16)],'YData',[pos(k,2),pos(k,17)],'ZData',[pos(k,3),pos(k,18)]); set(L2,'XData',[pos(k,4),pos(k,16)],'YData',[pos(k,5),pos(k,17)],'ZData',[pos(k,6),pos(k,18)]); set(L3,'XData',[pos(k,7),pos(k,16)],'YData',[pos(k,8),pos(k,17)],'ZData',[pos(k,9),pos(k,18)]); set(L4,'XData',[pos(k,10),pos(k,16)],'YData',[pos(k,11),pos(k,17)],'ZData',[pos(k,12),pos(k,18)]); set(L5,'XData',[pos(k,13),pos(k,16)],'YData',[pos(k,14),pos(k,17)],'ZData',[pos(k,15),pos(k,18)]); else k=1; set(hp1,'pos',[pos(k,1),pos(k,2),pos(k,3)]); axis([0 255 0 255 0 255]); set(hp2,'pos',[pos(k,4),pos(k,5),pos(k,6)]); set(hp3,'pos',[pos(k,7),pos(k,8),pos(k,9)]); set(hp4,'pos',[pos(k,10),pos(k,11),pos(k,12)]); set(hp5,'pos',[pos(k,13),pos(k,14),pos(k,15)]); set(hp6,'pos',[pos(k,16),pos(k,17),pos(k,18)]); end However, when I run handFig('fileName.csv'), I obtain the same error everytime: ??? Error while evaluating TimerFcn for timer 'timer-7' Invalid handle object. I figured that it might come from the function trying to create a new 'csv' and 'both' everytime, so I tried removing them, and feeding the function the data directly, without results. What is exactly the problem? Is there a solution? Thanks a lot!
I think it's because when you call doPlot in the timer for the first time, you pass in t1 as an argument, and it might not exist the first time. Does doPlot need t1 at all? I'd suggest modifying it so it's not used, and then your call to: t1=timer('TimerFcn','k=doPlot(hp1,hp2,hp3,hp4,hp5,hp6,L1,L2,L3,L4,L5,both,k)','Period', Dt,'ExecutionMode','fixedRate'); Note the missing t1 in the doPlot call. Either that, or initialise your t1 before you create the timer so it has some value to pass in. Update (as an aside, can you use pause(Dct) in a loop instead? seems easier) Actually, now I think it's a problem of scope. It took a bit of digging to get to this, but looking at the Matlab documentation for function callbacks, it says: When MATLAB evaluates function handles, the same variables are in scope as when the function handle was created. (In contrast, callbacks specified as strings are evaluated in the base workspace.) You currently give your TimerFcn argument as a string, so k=doPlot(...) is evaluated in the base workspace. If you were to go to the matlab prompt, run handFig, and then type h1, you'd get an error because h1 is not available in the global workspace -- it's hidden inside handFig. That's the problem you're running into. However, the workaround is to specify your function as a function handle rather than a string (it says function handles are evaluated in the scope in which they are created, ie within handFig). Function handles to TimerFcn have to have two arguments obj and event (see Creating Callback Functions). Also, that help file says you have to put doPlot in its own m-file to have it not evaluate in the base Matlab workspace. In addition to these two required input arguments, your callback function can accept application-specific arguments. To receive these input arguments, you must use a cell array when specifying the name of the function as the value of a callback property. For more information, see Specifying the Value of Callback Function Properties. It goes through an example of what you have to do to get this working. Something like: % create timer t = timer('Period', Dt,'ExecutionMode','fixedRate'); % attach `k` to t so it can be accessed within doPlot set(t,'UserData',k); % specify TimerFcn and its extra arguments: t.TimerFcn = { #doPlot, hp1, hp2, hp3, ...., both }; start(t) Note -- the reason k is set in UserData is because it needs to be somehow saved and modified between calls to doPlot. Then modify your doPlot to have two arguments at the beginning (which aren't used), and not accept the k argument. To extract k you do get(timer_obj,'UserData') from within doPlot: function k=doPlot(timer_obj, event, hp1,hp2,hp3,.....) k = get(timer_obj,'UserData'); .... % rest of code here. % save back k so it's changed for next time! set(timer_obj,'UserData',k); I think that's on the right track - play around with it. I'd highly recommend the mathworks forums for this sort of thing too, those people are whizzes. This thread from the mathworks forum was what got me started and might prove helpful to you. Good luck!
What is a StackOverFlow exception in vb.net?
I dont even know what caused it in my application. What is it? I created a new instance of a class (the class was in another file), but at the first time I call a method it throws a StackOverFlow exception. The only thing that I think would logically throw a stackoverflow exception would be if someone downvoted Jon Skeet. But seriously now, what is it? I got around it by creating another class in the same file as the first class and using that to call the methods for me.
As a general rule, a stack overflow exception is caused by a recursive algorithm where the depth of recursion has exceeded the (typically) fixed stack limit. This is usually a result of a bug in the algorithm, but it may also be caused by the data structure you are applying the algorithm to being too "deep". Here's a trivial example of a buggy recursion (in no particular PL). function int length(list l) { if (empty(l)) { return 0; } else { return 1 + length(l); // should be 'return 1 + length(tail(l)); } } Calling length for any non-empty list will give a stack overflow in a typical programming language. But even if you correct the bug, calling the method for a long list is likely to cause a stack overflow. (The exception is when you use a language ... or more strictly a compiler ... that supports tail recursion optimization.)
A stackoverflow exception is when you exceed the allocated stack size, this generally occurs from recursively calling methods and never leaving, it can also be cause by various obscure method chaining. The issue is you probably have something to the extent of the following in the object. void MyMethod() { MyMethod(); } The calls will eat up and never free the stack space used because the calls never end execution and the entry point must remain. P.S. SO was named for the particular exception in question (this is fundamental and not limited to .NET), it's just a clever name for a developer site.
StackOverFlows Exceptions are exactly what they sound like, the stack overflows. Usually this is because you have a circular dependency in your methods. For instance method A calls B and B calls A. Or it could be a recursive method without a base case.
Without seeing the code it is impossible to tell why this happened but a StackOverflowException is thrown when a thread overflows its call stack. This most often occurs when a method calls itself recursively without any conditional break thus creating infinite recursion. Since each recursion creates a new stack frame an infinite recursion would theoretically create an infinite number of stack frames, I am sure you can now see why the term "stack overflow" is apt.
The Stack is where the computer stores a list of the functions that are currently being called, and the variables and parameters used. So if function Main calls function A, and then function A calls function B, and they use variables c, d and e, the stack will contain all of that information. However, the stack is only so big. So if function B then calls function C, which calls function D... etc, ending up with hundreds of nested functions, eventually, the stack will "overflow" - there isn't enough space to store another function call. As other people have noted, this usually happens with a recursive function (where function B calls function B, which then calls function B...) - eventually, the stack will overflow. You will need to find where that recursive function is being called, and why it isn't breaking out of the recursive loop when it's supposed to. Of course, the problem may not be that it's a buggy recursive algorithm - it may just be that the number of function calls exceeds the size of the stack. So if your algorithm has the potential to call a recursive function a few hundred times, it may be that.
This is usually caused by a recursive call to a function where that recursive call never terminates. You may get this in several ways. One way could be a recursive algorithm without a base case, another common one is creating objects A and B that create one of each other in the their constructors, etc. i recommend you step through the debugger and find out :)
I recently ported an old VB6 application to VB.NET which used a monstrous recursive function to sort an equally large amount of data. The algorithm was fine but execution consistently caused a stack overflow error. After much fiddling, I realized that VB was doing to much magic behind the code: easy type casting comes with a price. So the recursive function was relying way too much on late binding instead of using type variables and this resulted in HUGE amount of casting, parsing, etc. overhead (a single line of code could call from 2 to 10 functions...) which, obviously, made the stack overflow. TL;DR: Use DirectCast() and static binding (typed variables) to prevent VB from flooding the stack at runtime in a recursive function.
I had this problem occur, I noticed that I mis-typed lstEncounter. As I learned in my C++ class, the problem is the recursive algorithm of basically calling itself with the same parameters. My example where I got the error: Property Encounter(ByVal N As Integer) Get If N < lstEncounters.Count Then Return Encounter(N) Else Return Nothing End If End Get Set(value) lstEncounters(N) = value End Set End Property
I was having a Stackoverflow error. I was using a routine that added 1 to a counter then re called the same routine. About every 2500 to 3000 loops I got the stackoverflow error. I have added a DO...Loop that calls the routine, I use VB Express: BEFORE: Public Sub mainloop() Dim cntr as integer If cntr >= 5000 ( I just picked a number at random) me.close ( I close the program) ... (This is where I would manipulate the cntr for diff results) cntr = cntr + 1 ( increment the cntr) mainloop() (re call my loop) End IF End Sub (as I said before, after about 2500-3000 I would get the Stackoverflow error) AFTER: (Place this to execute first) Dim LoopCntr as integer Do While LoopCntr <= 40000 (this my number.. Use your own number) If LoopCntr > 40000 Then Exit Do End If mainloop() (The mainloop() has not been changed just the method of calling it) LoopCntr = LoopCntr + 1 Loop me.close (When LoopCntr reaches max it closes the program) (After adding the Do..Loop my program ran 40000 time without "Stackoverflow")