views:

423

answers:

4

What is the go with inlining functions or procedures in Delphi (specifically v2010 here, but I had the same issue with Turbo Delphi)?

There is some discalimer in the help about it may not always inline a function because of "certain criteria" whatever that means.

But I have found that generally inlining functions (even very simple ones that have 3 or 4 lines of code) slows down code rather than speeds it up.

A great idea would be a compiler option to "inline everything". I don't care if my exe grows by 50% or so to get it working faster.

Is there a way I can force Delphi to really inline code even if it is not decided to be inlinded by the compiler? That would really help. Otherwise you need to do "manual inlining" of replicating the procedure code throughout multiple areas of your code with remarks like "//inlining failed here, so if you change the next 5 lines, change them in the other 8 duplicate spots this code exists"

Any tips here?

+10  A: 

There's a compiler option for automatic inlining of short routines. In Project Options, under Delphi Compiler -> Compiling -> Code Generation, turn "Code inlining control" to Auto. Be aware, though, that this should only be on a release build, since inlined code is difficult to debug.

Also, you said that you don't mind making your program larger as long as it gets faster, but that often inlining makes it slower. You should be aware that that might be related. The larger your compiled code is, the more instruction cache misses you'll have, which slows down execution.

If you really want to speed your program up, run it through a profiler. I recommend Sampling Profiler, which is free, is made to work with Delphi code (including 2010) and doesn't slow down your execution. It'll show you a detailed report of what code you're actually spending the most time executing. Once you've found that, you can focus on the bottlenecks and try to optimize them.

Hope this helps, and welcome to StackOverflow! Feel free to come back with any more questions in the future. :)

Mason Wheeler
Code inlining control set to auto didn't help.Sampling Profiler is great. Very helpfull in showing where the bottlenecks are in real stats. Even if it really showed me what I already new. It will come in handy in the future for sure.Thanks.
TallGuy
+2  A: 

Inlining can make things slower in some cases. The inlined function may increase the number of CPU registers required for local variables. If there aren't enough registers available variables will be located in memory instead, which makes it slower.

If the function isn't inlined it will have (almost) all CPU registers available.

I've found that's it's typically not a good idea to inline functions containing loops. They will use a couple of variables which are likely to end up in memory, making the inlined code slower.

Giel
Increasing the number of bytes required to run a certain algorithm, will also use up more the CPU cache. In rare cases this could also have an effect.
Lars D
Lars +1 - except that it's not that rare.
Barry Kelly
+1  A: 

If you want to force inlining then use include files. You need to make sure you declare the correct variables, and then use {$I filename.inc}. That will always inject that specific code right where you want it, and make it easier to maintain if you need to change it.

Keep in mind that the compiler is written by people way smarter then most mere mortals (including myself) and has access to more information when deciding to inline or not, so when it doesn't inline it probably has a good reason.

Jim McKeeth
A: 

If I understood one of the FPC compiler devels (which has the same issue) correctly, inlining can only happen when the routine to be inline was already compiled.

IOW if you make the unit with the inlined-to-be functions a "leaf" unit, and put it as first in the uses clause of your project (.dpr), it should be ok. Note that with "leaf" unit, I mean a unit that has no dependancy on other units in the project, iow only on already compiled units.

I wouldn't be surprised it was the same in Delphi, since it shares an unit system based on the same principles.

It is also pretty unfixable without violating separate compilation principles.

Marco van de Voort