• Welcome to Valhalla Legends Archive.
 

Regarding the efficiency of member functions

Started by Arta, December 03, 2003, 09:18 AM

Previous topic - Next topic

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:


*(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?

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.

dxoigmn

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.

Arta

#3
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 :)

dxoigmn

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.

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.
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Arta

Have it implemented now, as adron suggested. Will report back on efficiency.

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.
Eibro of Yeti Lovers.

Kp

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.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

Eibro

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.
Eibro of Yeti Lovers.

iago

Note that inline gives you the best of both worlds.  It's clean, organized code with no slowdown.
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


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?
Quote from: iago on February 02, 2005, 03:07 PM
Yes, you can't have everybody...contributing to the main source repository.  That would be stupid and create chaos.

Opensource projects...would be dumb.

iago

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.
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


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.
Eibro of Yeti Lovers.

Skywing

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.