Valhalla Legends Archive

Programming => General Programming => C/C++ Programming => Topic started by: Arta on December 03, 2003, 09:18 AM

Title: Regarding the efficiency of member functions
Post by: Arta on December 03, 2003, 09:18 AM
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:


*(DWORD*)(Buffer            ) = 0x00000001;
*(DWORD*)(Buffer + 0x04) = 0x00000002;
*(DWORD*)(Buffer + 0x08) = 0x00000003;



Packet.Add((DWORD)0x00000001);
Packet.Add((DWORD)0x00000002);
Packet.Add((DWORD)0x00000003);

// ...

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

   return;
}


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?
Title: Re:Regarding the efficiency of member functions
Post by: Adron on December 03, 2003, 10:19 AM
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.
Title: Re:Regarding the efficiency of member functions
Post by: dxoigmn on December 03, 2003, 11:44 AM
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.
Title: Re:Regarding the efficiency of member functions
Post by: Arta on December 03, 2003, 12:08 PM
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 :)
Title: Re:Regarding the efficiency of member functions
Post by: dxoigmn on December 03, 2003, 12:26 PM
Quote from: Arta[vL] on December 03, 2003, 12:08 PM
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 :)

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).

Makes it sound like that is your cause.
Title: Re:Regarding the efficiency of member functions
Post by: iago on December 03, 2003, 12:31 PM
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.
Title: Re:Regarding the efficiency of member functions
Post by: Arta on December 03, 2003, 02:12 PM
Have it implemented now, as adron suggested. Will report back on efficiency.
Title: Re:Regarding the efficiency of member functions
Post by: Eibro on December 03, 2003, 03:23 PM
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.
Title: Re:Regarding the efficiency of member functions
Post by: Kp on December 03, 2003, 03:36 PM
Quote from: Eibro on December 03, 2003, 03:23 PM
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.

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.
Title: Re:Regarding the efficiency of member functions
Post by: Eibro on December 03, 2003, 03:58 PM
Quote from: Kp on December 03, 2003, 03:36 PM
Quote from: Eibro on December 03, 2003, 03:23 PM
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.

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.
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.
Title: Re:Regarding the efficiency of member functions
Post by: iago on December 03, 2003, 04:55 PM
Note that inline gives you the best of both worlds.  It's clean, organized code with no slowdown.
Title: Re:Regarding the efficiency of member functions
Post by: Zakath on December 04, 2003, 01:10 PM
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?
Title: Re:Regarding the efficiency of member functions
Post by: iago on December 04, 2003, 01:53 PM
Quote from: Zakath on December 04, 2003, 01:10 PM
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?

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

And different compilers might handle that differently, it's hard to say.
Title: Re:Regarding the efficiency of member functions
Post by: Eibro on December 04, 2003, 02:28 PM
If you really want it inlined, you can shut the compiler up with __forceinline (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/tions_9.asp) (VC specific)
There's other situations besides code size where the compiler will not inline a function.
Title: Re:Regarding the efficiency of member functions
Post by: Skywing on December 04, 2003, 03:05 PM
Quote from: Zakath on December 04, 2003, 01:10 PM
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?
Most compilers have an option to let the compiler choose any functions it wants to be inline.  This would be a better idea.
Title: Re:Regarding the efficiency of member functions
Post by: Etheran on December 05, 2003, 02:05 PM
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.
Title: Re:Regarding the efficiency of member functions
Post by: Telos on December 05, 2003, 03:23 PM
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.
Title: As an extension to Skywing's comment
Post by: Kp on December 05, 2003, 03:55 PM
Quote from: Skywing on December 04, 2003, 03:05 PM
Quote from: Zakath on December 04, 2003, 01:10 PM
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?
Most compilers have an option to let the compiler choose any functions it wants to be inline.  This would be a better idea.

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).
Title: Re:Regarding the efficiency of member functions
Post by: Banana fanna fo fanna on December 05, 2003, 10:16 PM
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.
Title: Re:Regarding the efficiency of member functions
Post by: Arta on December 06, 2003, 10:13 AM
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?
Title: Re:Regarding the efficiency of member functions
Post by: Adron on December 06, 2003, 10:24 AM
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.