Uwe Raabe 2055 Posted May 17 48 minutes ago, msohn said: Does that mean that passing the variables as arguments to local routines would generate more efficient code? Usually, yes! Peganza Pascal Analyzer even has a report for that: Quote Local subprograms with references to outer local variables (OPTI6) This section shows nested local procedures, with references to outer local variables. Those local variables require some special stack manipulation so that the variables of the outer routine can be seen by the inner routine. This results in a good bit of overhead. 1 2 Share this post Link to post
dummzeuch 1501 Posted May 17 1 hour ago, msohn said: Does that mean that passing the variables as arguments to local routines would generate more efficient code? Yes. But only if they are simple types or (for complex types like large records or arrays) if they are passed by reference (var/const). On the other hand: I doubt that this makes much of a difference for most programs. Share this post Link to post
David Heffernan 2345 Posted May 17 1 hour ago, dummzeuch said: Yes. But only if they are simple types or (for complex types like large records or arrays) if they are passed by reference (var/const). I'm not sure that this is true. Share this post Link to post
Kas Ob. 121 Posted May 17 Quote Local subprograms with references to outer local variables (OPTI6) This section shows nested local procedures, with references to outer local variables. Those local variables require some special stack manipulation so that the variables of the outer routine can be seen by the inner routine. This results in a good bit of overhead. I disagree with this statement, Delphi compiler uses the stack (indexed access) always when ran out of register with optimized enabled or disabled (in case disabled it always will depend on them), in case very simple local procedure then yes there might be an overhead due the need for register for the parent hence will switch for indexed stack access ( slower or lets say overhead), but in most cases local procedure are used to decrease complexity and increase readability, this infer the high local variables used then most likely the parent is already using the indexed stack access for most of its local variables, introducing the local procedure/function in this case might give the compiler the ability to use the register again specially in case moving loops to local procedures hence increasing the speed even with the few stack preparing overhead instructions, So i don't i agree with that statement, it is relative to some degree and based on the case of the usage, again with complex procedures with more than one loop or even nested ones, extracting some of the code to local procedure might be useful mostly for readability, decrease complexity, and might enhance the performance, but who knows how the compiler will behave, in many cases rearranging the local declared variables order can enhance the performance when the compiler use registers for the first encountered variables, hence using or switching the variables order might yield better performance but this will not help the local procedure with loops always, specially if it is was stack accessed to begin with, and the compiler lost the track or simply overwhelmed with variables or the code. Also lets not forget that parameters passed to the parent p/f are already in registers so the chance to lose registers usage for local variables is already amplified greatly. Share this post Link to post
David Schwartz 426 Posted May 21 Whenever I'm tempted to do this, I look very hard at the likelihood that the code I'm dealing with could be moved into a class. If it's only used once, right there, then I may just leave it as-is. But maybe with a bit more abstraction it could be more useful. That said, it's not something I ever think of doing very often because it's a form of encapsulation that's mostly used in classes. Share this post Link to post
Stefan Glienke 1998 Posted May 21 On 5/17/2024 at 12:58 PM, Kas Ob. said: in many cases rearranging the local declared variables order can enhance the performance when the compiler use registers for the first encountered variables, hence using or switching the variables order might yield better performance I've seen this mentioned before yet I never found this to be true - at least not in recent (past decade) Delphi versions. 1 Share this post Link to post
Patrick PREMARTIN 68 Posted May 22 On 5/16/2024 at 6:22 AM, Tommi Prami said: Yellow, Could not think what else to call then as "Local Global variables" So let me show. function Foo(...) var LListOfVariables: TSomeType; procedure Bar1; begin // Complex proc that might or might not use variables defined above, and/or change them end; procedure Bar2; begin // Complex proc that might or might not use variables defined above, and/or change them end; ... begin // Func main body that might or might not call local procs end; For me this is very hard to wrap my brains around. For me this pattern requires lot of thinking and overloads my limited memory, to keep in mind that call to local procedure might touch the local variable, even it is not directly passed into them. I don't have anything against local methods, they wrap nicely some local need, that is specific for that parent method, and only for that. But fight are they good idea at first place, is another matter. -Tee- Hi Just a question for me : why do you declare variables before the nested methods if this behavior disturbs you ? 1 Share this post Link to post
Kas Ob. 121 Posted May 22 7 hours ago, Stefan Glienke said: I've seen this mentioned before yet I never found this to be true - at least not in recent (past decade) Delphi versions. Also i am failing now to write one good example to show that behavior with XE8. Share this post Link to post
Tommi Prami 130 Posted May 23 (edited) On 5/22/2024 at 9:42 AM, Patrick PREMARTIN said: Hi Just a question for me : why do you declare variables before the nested methods if this behavior disturbs you ? I don't. Why would I complain about it if it would be my own fault 😄 But there are people that has this habit, in component vendors, open source library writes, possibly in coworkers etc... Edited May 23 by Tommi Prami Share this post Link to post
Brandon Staggs 270 Posted May 23 3 hours ago, Tommi Prami said: I don't. Why would I complain about it if it would be my own fault 😄 But there are people that has this habit, in component vendors, open source library writes, possibly in coworkers etc... Variables declared before or below sub-procedures are a way to control variable scope. The use of sub-procedures/functions can be a way to clarify the code in the main procedure by moving implementation of if/then logic out of the way, or to facilitate re-use inside of that procedure, when the author doesn't feel it appropriate to move the code into a class method instead. Personally, I most often use sub-procedures to make code easier to follow in the main method implementation, when that code is not relevant to the rest of the class and shouldn't be part of its interface (private or otherwise). However, when I do this, if I start making several sub-procedures, it's a signal to me that I should probably be refactoring or making a new class for that work. Share this post Link to post
corneliusdavid 213 Posted May 23 I have found myself writing a method that then got longer than I originally anticipated. In order to keep it to a manageable size, I would separate sections out to sub-procedures but then find it necessary to refactor and the decision to send parameters to these new subroutines or not generally ends up with these "local global variables" instead so I don't have to change so much of the code. Yes, it's a little lazy but I never considered any performance hit until reading this thread. Still, for these programs, the performance is usually negligible. And for the record, I never start out with the intention of writing nested procedures like this, it only happens after-the-fact during a refactor process. 1 Share this post Link to post