Discussion:
Mixing code in a class and code outside of a class and performance
(too old to reply)
Colin B Maharaj
2008-08-05 07:18:55 UTC
Permalink
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
X-Antivirus: avast! (VPS 080804-0, 08/04/2008), Outbound message
X-Antivirus-Status: Clean
NNTP-Posting-Host: 190.58.103.87
Message-ID: <4897fedf$***@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1217920735 190.58.103.87 (5 Aug 2008 00:18:55 -0700)
Lines: 48
Path: number1.nntp.dca.giganews.com!border1.nntp.dca.giganews.com!nntp.giganews.com!nx01.iad01.newshosting.com!newshosting.com!203.109.252.33.MISMATCH!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mail
Bytes: 1602
Xref: number1.nntp.dca.giganews.com borland.public.cppbuilder.language.cpp:20972

Remember this code is hypothetical.
Say I have a class like this...


class TMyClass
{

public:
TMyClass();
~TMyClass();
void bar();

private:
void foo();
};

// Then....
TMyClass::TMyClass() { }
TMyClass::~TMyClass() { }
void TMyClass::foo() { }

// Then all of a sudden...
void fastmanip(int & y)
{
int x = y;
asm
{
mov eax, x
shl eax, 1
mov x, eax
}
y = x
}

void TMyClass::bar()
{
int w;
fastmanip(w);
}

Question:
Seeing how I called a function that was just there, not part of the
class, how does this affect the performance. Is there any overhead
of calling this code if it were not part of the class? Should I put
it in the class?
Alan Bellingham
2008-08-05 08:05:18 UTC
Permalink
Post by Colin B Maharaj
Seeing how I called a function that was just there, not part of the
class, how does this affect the performance.
It shouldn't do.
Post by Colin B Maharaj
Is there any overhead
of calling this code if it were not part of the class? Should I put
it in the class?
No. It has nothing to do with your class (it doesn't even access any
members), so it does not belong in your class. Since it doesn't have
anything to do with anything else either, it doesn't belong in any other
class.

Only put stuff into a class that needs to be in that class. This isn't
Java, so you don't need to cope with Java's requirement that everything
be part of some class.

Alan Bellingham
--
Team Browns
<url:http://www.borland.com/newsgroups/> Borland newsgroup descriptions
<url:http://www.borland.com/newsgroups/netiquette.html> netiquette
Alan Bellingham
2008-08-05 09:01:08 UTC
Permalink
It could affect perfomance if you defined functions as inlined.
That's nothing to do with whether the function is a class method,
though, even though it's related to performance in general.
Also I'd like to point out that the function bar() may be declared as static
because it does not deal with a class object.
It could be - but it's bad, bad design to make it a class method at all
if it doesn't refer to anything inside the class.

But you do raise a good point - normal class methods do have some
overhead, since they pass the invisible extra parameter 'this'.

Alan Bellingham
--
Team Browns
ACCU Conference 2009: to be announced
Vladimir Grigoriev
2008-08-05 10:35:27 UTC
Permalink
Post by Alan Bellingham
Also I'd like to point out that the function bar() may be declared as static
because it does not deal with a class object.
It could be - but it's bad, bad design to make it a class method at all
if it doesn't refer to anything inside the class.
I can not agree with your statement. For example in the following desing
taken from Turbo Vision I don't see anything awful.

class TObject
{

public:

TObject();
static void destroy( TObject * ); // <==

protected:

virtual ~TObject() = 0;
virtual void shutDown() = 0;

private:

TObject( const TObject & );
TObject & operator=( const TObject & );

};

inline void TObject::destroy( TObject *obj )
{
if( obj != 0 )
obj->shutDown();
delete obj;
}

Vladimir Grigoriev
Alan Bellingham
2008-08-05 11:32:15 UTC
Permalink
Sorry Alan.
I did not read your statement correctly.:)
*Now* you tell me! And after I did a whole critique on your example.

*grin*

Alan Bellingham
--
Team Browns
ACCU Conference 2009: to be announced
Vladimir Grigoriev
2008-08-05 11:34:40 UTC
Permalink
Post by Alan Bellingham
Also I'd like to point out that the function bar() may be declared as static
because it does not deal with a class object.
It could be - but it's bad, bad design to make it a class method at all
if it doesn't refer to anything inside the class.
Sorry Alan.
I did not read your statement correctly.:)

Vladimir Grigoriev
Alan Bellingham
2008-08-05 11:30:48 UTC
Permalink
"Vladimir Grigoriev" <***@mail.ru> wrote:

[I said]
Post by Vladimir Grigoriev
Post by Alan Bellingham
It could be - but it's bad, bad design to make it a class method at all
if it doesn't refer to anything inside the class.
I can not agree with your statement. For example in the following desing
taken from Turbo Vision I don't see anything awful.
class TObject
{
TObject();
static void destroy( TObject * ); // <==
virtual ~TObject() = 0;
virtual void shutDown() = 0;
TObject( const TObject & );
TObject & operator=( const TObject & );
};
inline void TObject::destroy( TObject *obj )
{
if( obj != 0 )
obj->shutDown();
delete obj;
}
Could you point to any member in there that isn't referring to a
TObject?

c'tor - nope, that constructs one.

destroy() - nope, that destroys a TObject.

d'tor - that's the standard way of destroying an object

shutdown() - we can't tell because it's virtual, but it's pretty safe to
assume that it's going to be overridden by something that will refer to
the content of the object.

And I'm assuming that the copy c'tor and operator assignment aren't
actually implemented, in order to prevent assignment.

The only method you've shown the content of is destroy(), and that is
explicitly a method that calls a protected member function on the object
passed in. I'd be embarrassed by the obvious flaw in the implementation,
but it belongs in the class. IMO, it'd be better written as a
non-static:

inline void TObject::destroy()
{
shutDown();
delete this;
}

And actually, once you done that, then since the d'tor and shutDown()
are both virtual, and you presumably don't want to shut down except when
you're destroying the object, then the content of shutDown() could be
moved into the destructor anyway, and destroy() could disappear, and ...

Oh, hold on, that then allows a TObject to be put on the stack. Which is
permitted in C++ classes, but breaks TObject, which isn't.

I'll modify my original statement:

In C++, it's almost always bad, bad design to make a function a
class method if it doesn't refer to anything inside the class.

Alan Bellingham
--
Team Browns
ACCU Conference 2009: to be announced
Vladimir Grigoriev
2008-08-05 12:10:14 UTC
Permalink
Post by Alan Bellingham
The only method you've shown the content of is destroy(), and that is
explicitly a method that calls a protected member function on the object
passed in. I'd be embarrassed by the obvious flaw in the implementation,
but it belongs in the class. IMO, it'd be better written as a
inline void TObject::destroy()
{
shutDown();
delete this;
}
The problem is that the TObject is a base class for many derived classes. So
either destroy should be defined as a virtual function or it should be a
static function which accepts an object as a parameter. What is better? IMO
it is better to use a static function instead of a virtual function which
deletes the object to which it belongs.
The design of TObject was done such a way that to reject creating objects of
derived classes in stack.

Vladimir Grigoriev
Alan Bellingham
2008-08-05 12:16:44 UTC
Permalink
Post by Vladimir Grigoriev
The problem is that the TObject is a base class for many derived classes. So
either destroy should be defined as a virtual function or it should be a
static function which accepts an object as a parameter. What is better? IMO
it is better to use a static function instead of a virtual function which
deletes the object to which it belongs.
A static function which immediately forwards on to a virtual function
(or pair of them) effectively *is* the virtual function. Given the
requirement that prevents the normal "delete myTObject;" syntax being
used, then using a static method as an object sink is defensible, though
it smacks a little too much to me of defensive programming. I'd *prefer*
the virtual function version, since it'd not attempt protect me against
trying to destroy a null pointer. If I don't know whether a pointer
might be null or not, then I'm way too confused to be proceeding anyway.

I'm still amused by

inline void TObject::destroy( TObject *obj )
{
if( obj != 0 )
obj->shutDown();
delete obj;
}

rather than

inline void TObject::destroy( TObject *obj )
{
if( obj != 0 )
{
obj->shutDown();
delete obj;
}
}

If you're going to protect against idiot users passing in NULL pointers,
you might as well not pass any such NULL on to delete itself, even
though it's not harmful.
Post by Vladimir Grigoriev
The design of TObject was done such a way that to reject creating objects of
derived classes in stack.
That was my assumption.

Alan Bellingham
--
Team Browns
ACCU Conference 2009: to be announced
Vladimir Grigoriev
2008-08-05 13:07:20 UTC
Permalink
Post by Alan Bellingham
I'm still amused by
inline void TObject::destroy( TObject *obj )
{
if( obj != 0 )
obj->shutDown();
delete obj;
}
rather than
inline void TObject::destroy( TObject *obj )
{
if( obj != 0 )
{
obj->shutDown();
delete obj;
}
}
If you're going to protect against idiot users passing in NULL pointers,
you might as well not pass any such NULL on to delete itself, even
though it's not harmful.
There is nothing harmful to delete a pointer that is equal to 0 and it is a
general practice in C++ because it is a safe deletion.

Vladimir Grigoriev
Alan Bellingham
2008-08-05 13:17:15 UTC
Permalink
Post by Vladimir Grigoriev
Post by Alan Bellingham
you might as well not pass any such NULL on to delete itself, even
though it's not harmful.
There is nothing harmful to delete a pointer that is equal to 0
I think that's what I said. But given you that you *know* the pointer is
0 (you just checked!), you might as well not pass it to delete.

Alan Bellingham
--
Team Browns
ACCU Conference 2009: to be announced
Vladimir Grigoriev
2008-08-05 08:59:14 UTC
Permalink
Post by Colin B Maharaj
Remember this code is hypothetical.
Say I have a class like this...
class TMyClass
{
TMyClass();
~TMyClass();
void bar();
void foo();
};
// Then....
TMyClass::TMyClass() { }
TMyClass::~TMyClass() { }
void TMyClass::foo() { }
// Then all of a sudden...
void fastmanip(int & y)
{
int x = y;
asm
{
mov eax, x
shl eax, 1
mov x, eax
}
y = x
}
void TMyClass::bar()
{
int w;
fastmanip(w);
}
Seeing how I called a function that was just there, not part of the
class, how does this affect the performance. Is there any overhead
of calling this code if it were not part of the class? Should I put
it in the class?
It could affect perfomance if you defined functions as inlined.
Also I'd like to point out that the function bar() may be declared as static
because it does not deal with a class object. I think your example is only
to illustrate your question however I'd like to add also that it is not a
good practice then such simple types as int are passed by reference. Also
there is no any need to use the asm instruction. I'd rewrite your functions
the following way

int fastmanip(int y)
{
return y << 1;
}

void TMyClass::bar()
{
int w;
w = fastmanip(w);
}

Vladimir Grigoriev
AlexB
2008-08-05 10:43:09 UTC
Permalink
Is there any overhead of calling this code
if it were not part of the class?
There is additional hidden parameter for class functions (this) which
is unnecessary in your case. So non-class function should be faster.
--
Alex
Chris Uzdavinis (TeamB)
2008-08-05 13:33:50 UTC
Permalink
Post by Colin B Maharaj
Seeing how I called a function that was just there, not part of the
class, how does this affect the performance. Is there any overhead
of calling this code if it were not part of the class? Should I put
it in the class?
You can think of C++ as transforming the code into C code. Then when
you see something like this:

class X
{
public:
void foo(int something);

private:
int data;
};


It can be thought of as silently, inside the compiler, becomming a
"normal", free-standing C function like this:

struct X
{
int data;
};

void X__foo(X * this, int something();


Of course, all the calls to x->foo(123) would get translated into
something like this:

X x;
X__foo(&x, 123);

Once you think of it this way, you'll see that it makes no difference
whether the function is a member or a free-standing function.
Performance-wise, they're all equivalent in just about every way.
(Unless, of course, the member function is declared "virtual", in
which case an extra level of indirection penalty may be incurred.)
--
Chris (TeamB);
Remy Lebeau (TeamB)
2008-08-05 17:20:33 UTC
Permalink
Post by Colin B Maharaj
Seeing how I called a function that was just there, not part of the
class, how does this affect the performance.
It doesn't.
Post by Colin B Maharaj
Is there any overhead of calling this code if it were not part of the
class?
No. If anything, there is less ovrhead, because there is no 'this' pointer
to setup as part of the call.
Post by Colin B Maharaj
Should I put it in the class?
The function doesn't directly reference any of the class members or methods,
so there is no reason to make it part of the class.


Ganbit
Colin B Maharaj
2008-08-06 23:14:37 UTC
Permalink
Thanks all for you insight....
:)
Post by Colin B Maharaj
Remember this code is hypothetical.
Say I have a class like this...
Loading...