Archived

This topic is now archived and is closed to further replies.

"private:" data members SLOOOW

This topic is 5799 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Benchmarking: 1) code as below in source: 17.3 seconds 2) as below but "void" setx member function with no return: 17.5 seconds (!) 3) as below but passing i by value instead of reference in setx: 19.0 seconds 4) using "public:" data members and "v1.x" instead of set/get routines: 3.8 seconds. Can things be speeded up without the cretinous sin of public data members? edit: 5) solved using "inlines". 3.9 seconds. - seb
 float Vect::getx() const { return xcoord; } Vect &Vect::setx(const float & value) { xcoord = value; return *this; } int main() { int i=0; float x=0; Vect v1(0,0,0); long time0=GetTickCount(); for(;i<1000000000;++i) { v1.setx(i); x=v1.getx(); } long time1=GetTickCount(); cout << time1-time0; return 0; }
Edited by - bsxrider on January 29, 2002 7:53:53 AM

Share on other sites
You should put your accessor member functions in the header of your class and declare them as 'inline'.

Here's a better implementation of your class :

 class Vect{private: float xcoord;public: inline float getx() const { return xcoord; } inline void setx( float value) { xcoord = value; }};

This way, accesses to xcoord should be as fast as if it were accessed directly.

Note : you don't need to use references to pass const standard type arguments (int/float/char/...), you won't have any speed increase for this.

Edited by - Prosper/LOADED on January 29, 2002 7:44:25 AM

Share on other sites
well, I'd use public variables for a vector class, but if you are dead set on keeping them private you can always declare the functions inline.

eg
 inline float Vect::GetX(void)const ;

too slow

Edited by - Sandman on January 29, 2002 7:49:11 AM

Share on other sites
Ahhh. I tried to "inline" my functions as another test but it was coming up as errors, didn''t realise thery ahd to go with the definitions.

3.9 seconds.

Good stuff

- seb

Share on other sites
quote:

you don''t need to use references to pass const standard type arguments (int/float/char/...), you won''t have any speed increase for this.

Yeah I know, but my experiment in the first post shows that reference actually WAS slightly faster. However, with the tuples inlined the time is EXACTLY the same either way.

- seb

Share on other sites
Either you have a REALLY crappy compiler, or you are compiling a debug version (or both ).

If you want to do ANY kind of benchmarking, you should compiler a release version, preferably with full optimization. Benchmarking on debug code is useless, and does not say/mean anything.

Share on other sites
I always compile on Release. MSVC++6. Optimisations set to "maximum" speed.

What do you think is crappy about my compiler?

- seb

Share on other sites
If you do compile a realease, then I apologize. And I use the MSVC 6 compiler myself, and it''s nowhere near crappy

Anywyas, if you don''t want to make your members public, then inlined functions is probbaly the fastest. Just try them and choose the fastest one.

Share on other sites
i find that very wierd too. vc++ should be inlining those functions due to their size.

To the vast majority of mankind, nothing is more agreeable than to escape the need for mental exertion... To most people, nothing is more troublesome than the effort of thinking.

Share on other sites
Just loaded up the options bit.

Under "Optimizations" there''s an option called "Inline function expansion". Don''t know what it means really but I changed it to "any suitable (from __inline) and it made no difference.

If I put the member functions inside the class definition then they''re automatically inlined, it just seems to be if you declare it in the class and have the function in a separate file that it doesn''t automaticvally inline them. Interestingly in this case it would let you speciify that they''re inlined either.

- seb

Share on other sites
PS: if your test is this simple, I would highly suggest not doing a timed trial at all. Write a program that calls each function to be examined and then look at the disassembly--that way you know exactly what you're talking about. I won't go through the pain and suffering of doing it (I already know how to--you should learn), but I guarantee that these methods all compile to the same code.

also, re:
quote:

If I put the member functions inside the class definition then they're automatically inlined, it just seems to be if you declare it in the class and have the function in a separate file that it doesn't automaticvally inline them. Interestingly in this case it would let you speciify that they're inlined either.

inline is a lot like #define macros, so whoever uses the inlined function has to have the definition of the function. If code doesn't, then the compiler will silently put the function out of line and replace it with a function call; in this way it's different than a macro, because in this case a macro would give you an error.

Edited by - Stoffel on January 29, 2002 4:57:28 PM

Share on other sites
Stoffel: no offence but surely a timed trial is a good idea? The assembler of all the options I listed better had NOT be the same - if it is then there''s a lot of wasted complexity in c++ !

- seb

Share on other sites
Timed trials can be useful, but they can also be rather inaccurate. There are too many variables. Background processes, page faults, disk caching, position of the hard drive''s read head, contents of the CPUs'' cache, and so on. Looking at the disassembly is the best way to avoid all that, and see _exactly_ what your compiler is doing.

Share on other sites
I don''t know if someone else mentioned this, but you do know that you do not have to declare member functions as inline w/ the actual "inline" keyword, don''t you? If you just define the functions right inside a class interface, it''s inlined. Saves some typing, as well.

Share on other sites
Do you have the standard or professional version of MSVC?
AFAIK, only the proferssional version has all the compiler optimizations (i suspose enterprise does too).

In a debug build those accessors won't be inlined, no matter what. Only in a release build. So again, if it truely is a time-critical piece of code, go public.

Standard timing methods are highly imprecise, and often inaccurate. It's a pre-emptive multi-threaded system, so you not inly measuring the time in your application, you're measuring time in other applications as well as in IRS (interraupt service routines).
You will measure _more_ accurately if you time for *less* than 10ms, because it is less likely that your app will be task-swapped during such a small interval. You will still be measuring time in ISRs.

How fast is your computer? The time for that loop ought to be less than half a second on anything around a gig.

Edited by - Magmai Kai Holmlor on January 29, 2002 9:57:43 PM

Share on other sites
Maybe I don''t know what I''m talking about but 3.9 secs or whatever is pretty darn good for 1 billion (1,000,000,000) iterations through your loop. I would tend to think if you wanted to find out how long a single execution of that loop takes divide 3.9 sec / 1,000,000,000 to find out how long it took to run. I think it comes out to 3.9 ns for the loop to complete 1 iteration. What was the point of your benchmark? It doesn''t really come out as obvious to me. Then again I am brain dead when I''m at work. Just my 0.02 cents.

Share on other sites
It ought to be 1tick (1ns on a gig) due to pipelining (or less with super-scaling, e.g. an Athlon XP).

...
Actually it's the same memory hole so super-scaling won't help. An XP may be able to set x,y,&z in the same amount of time as just setting x.

Edited by - Magmai Kai Holmlor on January 30, 2002 1:46:25 AM

Share on other sites
I''m a scientist, I know pretty much how to conduct a fair trial. Anything unnecessary to the running of windows was closed down, and I ran each test 3 times.

MKH: A have the pro versio, yes. And yes this is a release compile. 1/2 a second? I''d be very impressed. Try it on yours and see what you get.

- seb

Share on other sites
Did you conduct the tests in every possible order to avoid any order effects?

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost ]

Share on other sites
I don''t know what you call a scientist, but we''re all engineers here. Common legend has it that scientists trust theory while engineers trust results. Seeing as how my advice is so distasteful to you, I''ll just have to do the work myself and hope you''ll listen to me in the future (hey, I do that when I work with other scientists too--hmm, maybe it''s a course in scientist school, "How To Ignore your Engineers").

 #include class Test{ int m_priVar;public: int m_pubVar; int getPrivVar () { return m_priVar; }};int GettingPublicVar (Test &t){ return t.m_pubVar;}int GettingPrivateVar (Test &t){ return t.getPrivVar ();}

Disassembly:

PUBLIC ?GettingPublicVar@@YAHAAVTest@@@Z ; GettingPublicVar
; COMDAT ?GettingPublicVar@@YAHAAVTest@@@Z
_TEXT SEGMENT
_t$= 8 ?GettingPublicVar@@YAHAAVTest@@@Z PROC NEAR ; GettingPublicVar, COMDAT ; 13 : return t.m_pubVar; mov eax, DWORD PTR _t$[esp-4]
mov eax, DWORD PTR [eax+4]

; 14 : }

ret 0
?GettingPublicVar@@YAHAAVTest@@@Z ENDP ; GettingPublicVar
_TEXT ENDS
PUBLIC ?GettingPrivateVar@@YAHAAVTest@@@Z ; GettingPrivateVar
; COMDAT ?GettingPrivateVar@@YAHAAVTest@@@Z
_TEXT SEGMENT
_t$= 8 ?GettingPrivateVar@@YAHAAVTest@@@Z PROC NEAR ; GettingPrivateVar, COMDAT ; 18 : return t.getPrivVar (); mov eax, DWORD PTR _t$[esp-4]
mov eax, DWORD PTR [eax]

; 19 : }

ret 0
?GettingPrivateVar@@YAHAAVTest@@@Z ENDP ; GettingPrivateVar
_TEXT ENDS

The compiler generates the exact same types of instructions for each method, therefore there is no difference between the two, regardless of what your timed trials tell you.

Share on other sites
quote:
Original post by Stoffel
PS: if your test is this simple, I would highly suggest not doing a timed trial at all. Write a program that calls each function to be examined and then look at the disassembly--that way you know exactly what you''re talking about. I won''t go through the pain and suffering of doing it (I already know how to--you should learn), but I guarantee that these methods all compile to the same code.

quote:
Original post by BSXrider
The assembler of all the options I listed better had NOT be the same - if it is then there''s a lot of wasted complexity in c++ !

quote:
Original post by Stoffel
hope you''ll listen to me in the future

We have a bit of a comms tangle here. I did listen to your post, too closely in fact. It seemed to me that you said "these methods all compile to the same code". If you''d said "both" instead of "all" I might have seen your point, but instead I inferred that you meant ALL 5 of the options I''d listed. You see. My apologies

I agree with you on that disassembly though. Which is pretty much what options (4) and (5) in my original post determined, that the results were close enough the same. Because putting the function body in the class like you''ve done makes it automatically inlined.

quote:
Original post by Kylotan
Did you conduct the tests in every possible order to avoid any order effects?

I knew someone would ask that but couldn''t think of a concise way of wording it in my post. Yes, I repeated them in differing orders (ctrl-z and ctrl-y were well used )

- seb

Share on other sites
quote:
Original post by BSXrider
MKH: A have the pro versio, yes. And yes this is a release compile. 1/2 a second? I'd be very impressed. Try it on yours and see what you get.

If you remove the grossly inefficent accessors, the optimizing version of MSVC will eliminate that loop.
As such, it takes 0.000000000 seconds on my computer.
One other thing (that I missed earlier) that loop isn't just coping numbers around - it's performing a full-blown ANSI/IEEE interger to floating point conversion - an Expen\$ive operation.

IFF you insist on using an accessor, you need to return a non-const&.

 class Vect{public:float& x(){return v.x;}}

[edit: I need to learn how to type]

Edited by - Magmai Kai Holmlor on January 30, 2002 8:33:42 PM

Share on other sites
quote:
Original post by Stoffel
hmm, maybe it''s a course in scientist school, "How To Ignore your Engineers").

I believe thats a Marketing / Management class.

If the wind blows hard enough, even turkeys can fly

• Forum Statistics

• Total Topics
628732
• Total Posts
2984436

• 25
• 11
• 10
• 16
• 14