Valhalla Legends Forums Archive | C/C++ Programming | Regarding the efficiency of member functions

AuthorMessageTime
Arta
This is about the efficiency of classes, in particular, with the use of a packet class for adding/removing fields from packets and sending them (BNCS).

Given these two approaches:

[code]
*(DWORD*)(Buffer ) = 0x00000001;
*(DWORD*)(Buffer + 0x04) = 0x00000002;
*(DWORD*)(Buffer + 0x08) = 0x00000003;
[/code]

[code]
Packet.Add((DWORD)0x00000001);
Packet.Add((DWORD)0x00000002);
Packet.Add((DWORD)0x00000003);

// ...

void CPacket::Add(DWORD Value)
{
*(DWORD*)(Buffer + Length) = Value;
Length += 4;

return;
}
[/code]

It seems to me that the function call overhead & extra work performed by the class would make it considerably slower than creating a packet using the first method. Can anyone confirm/refute that? The first method is, however, rather eww both to read and code and is alltogether most inconvinient. In a system where speed is key, can someone suggest a good middle road?
December 3, 2003, 3:18 PM
Adron
Make the Add function inline. It might still be somewhat slower since you don't increase any length variable in the first approach, but the difference shouldn't be huge.
December 3, 2003, 4:19 PM
kamakazie
Wouldn't the network latency be a larger factor in speed than your packet class? Seems to be rather fruitless to do what you propose.
December 3, 2003, 5:44 PM
Arta
Not at all. The faster it runs, the less CPU time it consumes and the quicker my computer is able to do something else.

Edit: In other words, my intention is not to get packets to Battle.net faster. As you say, that would obviously be a fruitless exercise :)
December 3, 2003, 6:08 PM
kamakazie
[quote author=Arta[vL] link=board=30;threadid=4045;start=0#msg33420 date=1070474936]
Not at all. The faster it runs, the less CPU time it consumes and the quicker my computer is able to do something else.

Edit: In other words, my intention is not to get packets to Battle.net faster. As you say, that would obviously be a fruitless exercise :)
[/quote]

Bah! Saying:

[quote]
This is about the efficiency of classes, in particular, with the use of a packet class for adding/removing fields from packets and sending them (BNCS).
[/quote]

Makes it sound like that is your cause.
December 3, 2003, 6:26 PM
iago
Well, the first method is simply a memory write, which is reaonably fast. It's a single line.

The second is a function call, with 2 parameters, which takes 3 lines. Although I don't know how Intel implements piplining, I know that on MIPS and SPARC and I'm sure some others you lose a few clock cycles when you change the control path, making it slower.

Doing it inline, however, is probably, by far, the best way. For a short function like that, it would probably improve it a lot.

So bottom line: Adron is right.
December 3, 2003, 6:31 PM
Arta
Have it implemented now, as adron suggested. Will report back on efficiency.
December 3, 2003, 8:12 PM
Eibro
I find it extremely silly to worry about something as trivial as this.
Have you determined that this is a slowpoint in your program? A function call is a function call, it's dirt cheap.
December 3, 2003, 9:23 PM
Kp
[quote author=Eibro link=board=30;threadid=4045;start=0#msg33472 date=1070486581]
I find it extremely silly to worry about something as trivial as this.
Have you determined that this is a slowpoint in your program? A function call is a function call, it's dirt cheap.[/quote]

Repeatedly calling the function will be slower and require more room than inlining the call. It may be cheap for a few passes, but inlining or avoiding function usage will have a speed payoff -- particularly if this is in any sort of loop. It may not be a significant optimization, but ignoring performance boosting changes just because they seem "trivial" or "too much work for the gain" is a good habit if you want to end up with a really inefficient program.
December 3, 2003, 9:36 PM
Eibro
[quote author=Kp link=board=30;threadid=4045;start=0#msg33480 date=1070487402]
[quote author=Eibro link=board=30;threadid=4045;start=0#msg33472 date=1070486581]
I find it extremely silly to worry about something as trivial as this.
Have you determined that this is a slowpoint in your program? A function call is a function call, it's dirt cheap.[/quote]

Repeatedly calling the function will be slower and require more room than inlining the call. It may be cheap for a few passes, but inlining or avoiding function usage will have a speed payoff -- particularly if this is in any sort of loop. It may not be a significant optimization, but ignoring performance boosting changes just because they seem "trivial" or "too much work for the gain" is a good habit if you want to end up with a really inefficient program.
[/quote]Again, has it been determined that this is being called in a tight loop, and the function calls actually pose a slowdown? Premature optimization is a waste of time. At this stage in the game this is just silly. I'd be more worried about frying the bigger fish than possible detrimental function calls.
December 3, 2003, 9:58 PM
iago
Note that inline gives you the best of both worlds. It's clean, organized code with no slowdown.
December 3, 2003, 10:55 PM
Zakath
Hmm...this brings an interesting thing to mind. I seem to recall that the compiler will ignore the inline specifier if the function is too large. This being the case, why would you not declare every function as inline and just leave it to the compiler to sort things out?
December 4, 2003, 7:10 PM
iago
[quote author=Zakath link=board=30;threadid=4045;start=0#msg33640 date=1070565040]
Hmm...this brings an interesting thing to mind. I seem to recall that the compiler will ignore the inline specifier if the function is too large. This being the case, why would you not declare every function as inline and just leave it to the compiler to sort things out?
[/quote]

I've never heard about that, but it may still be true :)

And different compilers might handle that differently, it's hard to say.
December 4, 2003, 7:53 PM
Eibro
If you really want it inlined, you can shut the compiler up with __forceinline (VC specific)
There's other situations besides code size where the compiler will not inline a function.
December 4, 2003, 8:28 PM
Skywing
[quote author=Zakath link=board=30;threadid=4045;start=0#msg33640 date=1070565040]
Hmm...this brings an interesting thing to mind. I seem to recall that the compiler will ignore the inline specifier if the function is too large. This being the case, why would you not declare every function as inline and just leave it to the compiler to sort things out?
[/quote]
Most compilers have an option to let the compiler choose any functions it wants to be inline. This would be a better idea.
December 4, 2003, 9:05 PM
Etheran
Use good coding practice until you get your project done and THEN worry about optimization. A fully functional project > an optimized partially functional project by far.
December 5, 2003, 8:05 PM
Telos
Etheran - I am not sure that I agree with you. If a large project is not designed with oprimization in mind from the beginning the code may not be designed in a fashion that will allow it to be improved without much more significant effort. A working project is nice but having to backtrack and find memory leaks and other bits and pieces that can be modified to run just a bit faster is bad compared to keeping speed and [possibly] memory in mind when designing your software.
December 5, 2003, 9:23 PM
Kp
[quote author=Skywing link=board=30;threadid=4045;start=0#msg33658 date=1070571959]
[quote author=Zakath link=board=30;threadid=4045;start=0#msg33640 date=1070565040]
Hmm...this brings an interesting thing to mind. I seem to recall that the compiler will ignore the inline specifier if the function is too large. This being the case, why would you not declare every function as inline and just leave it to the compiler to sort things out?
[/quote]
Most compilers have an option to let the compiler choose any functions it wants to be inline. This would be a better idea.
[/quote]

Based on how gcc performs when given permission to do this, I recommend declaring as static any functions that 1) are not called across files and 2) you expect the compiler might try to inline. At least with gcc, it will completely skip emitting the function freestanding if all instances are successfully inlined (note that non-static functions might be linked from outside the file, so it can't be certain that those are all inlined - but static functions it knows everything about their linkage).
December 5, 2003, 9:55 PM
St0rm.iD
Get it working first, optimize later, BUT think ahead before you start.

You don't want to sweat optimization for a long time, but make sure you design with a little forethought.
December 6, 2003, 4:16 AM
Arta
You absolutely have to optimise as you go along. There is a place for optimisation after a project is complete - analysing your application for hotspots and concentrating on them, which allows you to identify regularly called or repetative code which may not be obvious during development - but not optimising as you go along just leaves you with much more work later.

It would be rather like cooking a meal with no seasoning, herbs, or flavourings (like stock or soy sauce). You could add them at the end, but if you add them as you go along, they influence the other flavours during cooking and you end up with a nicer meal :)

In other words, why write crap code and then fix it later? Isn't it easier just to write good code to start with?
December 6, 2003, 4:13 PM
Adron
If it's easier to write good code from the start, do it. If you have to spend time thinking about how to make it faster, don't do it until you see that you need to make it faster.

edit:
It's like spending three hours counting up the grains of salt when cooking your potatoes, and then when you're finally done, the meat is cold.

Instead of just throwing in a spoonful, getting it finished in time, and trusting that if there would be a few grains too few, the gravy will cover it anyway.
December 6, 2003, 4:24 PM

Search