Shaving some time
I was talking to a colleague the other day and got into a discussion regarding some ways of coding c++, such as whether to use division or bit shifting — almost all modern compilers can optimize this so it’s basically just a matter of what looks best. At the same time, we got into a minor discussion regarding references and pointers in c++. I made a small test and found some rather amusing results, which is quite obvious once you think about it, but still very scary considering how common it is to use the pointer construct:
// Compile using g++ -lrt -o lala lala.cpp #include <iostream> #include <time.h> int* lala_ptr() { int *y = new int; *y = 5; return y; } int& lala_ref() { int x =5; int &y = x; return y; } timespec diff(timespec start, timespec end) { timespec temp; if ((end.tv_nsec-start.tv_nsec)<0) { temp.tv_sec = end.tv_sec-start.tv_sec-1; temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; } else { temp.tv_sec = end.tv_sec-start.tv_sec; temp.tv_nsec = end.tv_nsec-start.tv_nsec; } return temp; } int main(int argc, char **argv) { timespec time1, time2, time3; clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1); for (unsigned int i=0;i<(unsigned int)-1;i++) { int &z = lala_ref(); } clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2); for (unsigned int i=0;i<(unsigned int)-1;i++) { int *z = lala_ptr(); delete z; } clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time3); std::cout << "Reference diff(" << time1.tv_sec << ":" << time1.tv_nsec << ", " << time2.tv_sec << ":" << time2.tv_nsec << ") = " << diff(time1, time2).tv_sec << ":" << diff(time1, time2).tv_nsec << std::endl; std::cout << "Pointer diff(" << time2.tv_sec << ":" << time2.tv_nsec << ", " << time3.tv_sec << ":" << time3.tv_nsec << ") = " << diff(time2, time3).tv_sec << ":" << diff(time2, time3).tv_nsec << std::endl; }
Below is a sample of the output generated by the test code above:
oan@laptop4:~/Projects/test$ ./testRefVsPointer Reference diff(0:3869272, 25:234466470) = 25:230597198 Pointer diff(25:234466470, 299:547382527) = 274:312916057
So, the question for you all, can you figure out what's wrong? 😉
Comments
3 Comments on Shaving some time
-
Carl-Erwin Griffith on
Tue, 9th Nov 2010 12:00
-
J Austin on
Sun, 6th Feb 2011 05:28
-
Oskar Andreasson on
Thu, 10th Feb 2011 21:41
Hi,
The overhead you seen is caused by new/delete function calls
and the returned reference points into the stack 🙂
Carl-Erwin is correct. The reference case uses a variable allocated on the stack and the reference that is returned is undefined because the referenced stack object no longer exists.
You would be better off to not use new and delete and just return a pointer to a variable on the stack. Violate the language in the same way in both cases. I’ll bet performance is the same if you do it that way.
Yupp, you are both correct. There are several errors in that code. However, the interesting part isn’t the return value per se, but the time difference in using a reference vs pointer and the cost of new/delete. Exactly as you both pointed out 😉 .
Tell me what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!
You must be logged in to post a comment.