473,396 Members | 1,990 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

runtime overhead of pure abstract classes

424 256MB
If I have an base class consisting exclusively of abstract methods, would I incur any runtime overhead due to vtable lookups when calling methods of derived classes?
May 13 '08 #1
7 3536
RRick
463 Expert 256MB
You shouldn't incur any overhead beyond the vtable lookup of a virtual method. Remember, abstract methods are virtual methods. Also, verification that abstract methods are implemented is dealt with by the compiler and does not directly affect runtime performance.

Hmmmm, a base class with only abstract methods. Can you have an abstract destructor? Sounds possible, but I've never seen one.
May 13 '08 #2
arnaudk
424 256MB
Thanks, RRick. I was going to use an abstract class to define an interface for a number of closely related classes, so that I can store objects of different (derived classes) in a single array, for example. I hadn't thought of the consequences of using abstract constructors/desctructors, that shouldn't present any problems, should it?
Also, I could in principle use compile-time or static polymorphism through templates, that would save me vtable lookups. If we're dealing with millions of graphics objects, for example, that should save a lot of rendering time, right? Although I think the code could get a little abstruse then.
May 14 '08 #3
RRick
463 Expert 256MB
You are talking about two issues here: class design and performance.

With your class design, you use abstract methods to force the derived class to implement them. This means the base class has no idea of what should be done.

You use virtual methods to allow overwriting but with a default behavior. In this case, it makes sense having the base class declare and define a virtual destruction. You want all of your derived classes to have one, but don't want to have to re-define a destructor if you don't need it.

Remember, use the correct design for the correct task.


As for performance of virtual methods, I simply don't worry about it. Vtable overhead is small (i.e. nano second small) and with Ghz machines, you can make millions or billions of vtable lookups in very little time.
May 14 '08 #4
arnaudk
424 256MB
OK. Just to check my idea is not flawed:
Say I'd like to put Fahrenheit and Celsius objects in the same vector array. To do this, I make F and C subclasses of a Temperature (T) class. Obviously, I don't have nor will ever have T objects, so the T class can be a purely abstract base class, then I can have vector<T> which will hold both F and C objects. The constructor/destructor of T can also be abstract if their counterparts differ in F and C classes. Does that sound right?

Now, since I'm running numerical analysis routines, the elements of the vector<T> will need to be iterated over roughly 1e12 times. So each 1 nanosecond vtable lookup translates to something around 1000 seconds or 15mins in total overhead. Not too bad, but is it worth the niceties of polymorphism here, or is there a better way?
May 14 '08 #5
weaknessforcats
9,208 Expert Mod 8TB
To do this, I make F and C subclasses of a Temperature (T) class. Obviously, I don't have nor will ever have T objects, so the T class can be a purely abstract base class, then I can have vector<T> which will hold both F and C objects. The constructor/destructor of T can also be abstract if their counterparts differ in F and C classes. Does that sound right?
Close but not quite. C++ does not support the Liskov Substitution Principle where you substitute a derived object for a base object. With C++ you substitute a derived class object by using a base class pointer or reference.

That means your vector has to be a vector<T&> or a vector<T*>.

And that means you should be using handles: vector<Handle<T> >.

Read this article: http://bytes.com/forum/thread651599.html.
May 14 '08 #6
arnaudk
424 256MB
So you mean something like this?
Expand|Select|Wrap|Line Numbers
  1. #include "Handle.h"
  2.  
  3. class Temperature
  4. {
  5. public:
  6.     virtual Temperature() = 0;
  7.     virtual ~Temperature() = 0;
  8.     virtual float inDegreesKelvin() = 0;
  9. };
  10.  
  11. class Celsius: public Temperature
  12. {
  13. public:
  14.     Celsius(const float& degrees) : _degrees(degrees) { }
  15.     ~Celsius() { }
  16.     float inDegreesKelvin() const { return _degrees + 273.15 };
  17.     static Handle<Temperature> newhandle();
  18. private:
  19.     const float _degrees;
  20. }
  21.  
  22. inline Handle<Temperature> Celsius::newhandle(const float& degrees) 
  23.  {
  24.      Celsius* t = new Celsius( degrees );
  25.      Handle<Temperature> rval(t);
  26.      return rval;
  27.  }
  28.  
  29. int main()
  30. {
  31.     Handle<Temperature> boiling = Celsius::newhandle(100) ;
  32. }
  33.  
Now boiling is a (smart) pointer to the base class?
May 14 '08 #7
RRick
463 Expert 256MB
Performance enhancements need to be compared to the total amount of time spent on performing a specific task.

In your example you are performing 10**12 operations. This means
  • 10**12 Vector accesses, object fetch and de-referencing
  • 10**12 method calls with parameter settings and register swapping
  • 10**12 Of actually doing something
In this type of environment, look up overhead is a small percent of the total time. I see no reason to try to improve performance on issues that take up 1% or less of my total time.
May 14 '08 #8

Sign in to post your reply or Sign up for a free account.

Similar topics

51
by: Noam Raphael | last post by:
Hello, I thought about a new Python feature. Please tell me what you think about it. Say you want to write a base class with some unimplemented methods, that subclasses must implement (or...
9
by: | last post by:
I don't understand. What's the difference in practice between 2 next lines? When I *must* use first line and when second? ------------- virtual int a(int b) = 0; virtual int a(int b);...
11
by: santosh | last post by:
Hello, I was going through the Marshal Cline's C++ FAQ-Lite. I have a doubt regarding section 33.10. Here he is declaring a pure virtual destructor in the base class. And again defining...
37
by: WittyGuy | last post by:
Hi, I wonder the necessity of constructor and destructor in a Abstract Class? Is it really needed? ? Wg http://www.gotw.ca/resources/clcm.htm for info about ]
4
by: Eric | last post by:
I was wondering what people thought about the information found at: http://g.oswego.edu/dl/mood/C++AsIDL.html Specifically, I am interested in the following recommendation: ---- Since...
7
by: sam_cit | last post by:
Hi Everyone, I wanted to know as to what is the exact difference between a virtual function and a pure virtual function? Thanks in advance!!!
6
by: Miguel Guedes | last post by:
Hello, I recently read an interview with Bjarne Stroustrup in which he says that pure abstract classes should *not* contain any data. However, I have found that at times situations are when it...
2
by: mmcgarry.work | last post by:
Hi, I would like to follow Stroustrup's advice of separating an object interface (abstract class) from an object implementation (concrete class), See Section 15.2.5 in Stroustrup 3rd Edition. ...
4
emibt08
by: emibt08 | last post by:
Hi. I know the title looks a little bit silly and that we can not have pure virtual static functions. But i've been wondering what approach to take to make the abstraction. This is the case: I have...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.