surprising template size and speed

C

charles.lobo

Hi,

I have recently begun using templates in C++ and have found it to be
quite useful. However, hearing stories of code bloat and assorted
problems I decided to write a couple of small programs to check. What I
expected was that there would be minor code bloat and some speed
improvement when using templates. However...

I wrote a basic list container (using templates), and a list container
(using virtual derived classes). I also tried with the std lib vector
class. I ran 1000000 inserts and accesses to all these lists and got
the following results (compiling on windows with microsoft compiler):

Size:
22,528 mytpl.exe
36,864 nonstd.exe
40,960 std.exe

The first is my template list, the second my non-template list, and the
third is using the std vector.

The first surprise was that my template list was actually *smaller*
than the non-template version! Very surprising. However, it's not all
good news. I then ran some timing tests.

Time:
875: running std.exe
1484: running nonstd.exe
1563: running mytpl.exe

As expected, the std vector is the fastest. However my template list
class is the *slowest*!!! This was definitly not expected.

Does anyone have any inputs on what's going on?

cheers,
/Charles
 
V

Victor Bazarov

[..]
As expected, the std vector is the fastest. However my template list
class is the *slowest*!!! This was definitly not expected.

Does anyone have any inputs on what's going on?

Not really. How can anyone tell anything about the performance of
_your_ program we cannot see, on _your_ computer, without any
ability to measure anything? Are you kidding?

V
 
C

charles.lobo

Victor said:
[..]
As expected, the std vector is the fastest. However my template list
class is the *slowest*!!! This was definitly not expected.

Does anyone have any inputs on what's going on?

Not really. How can anyone tell anything about the performance of
_your_ program we cannot see, on _your_ computer, without any
ability to measure anything? Are you kidding?

V
Hmmm.... well that's a good point. I couldn't find any way of uploading
my code.

However, it's pretty small, so I'll just paste it below
----------------------- Template List ----------------------------
template <class T>
class ListNode
{
public:
ListNode (T * pVal) {uVal = pVal;}
T * uVal;
ListNode<T>* uNext;
ListNode<T>* uPrev;

};

template <class T>
class MyTList
{
public:
MyTList () { vFirst = NULL; }

void Insert (T * e) {
ListNode<T> * ln;
ln = new ListNode<T> (e);
ln->uNext = vFirst;
ln->uPrev = NULL;
if (vFirst != NULL)
vFirst->uPrev = ln;
vFirst = ln;
}
ListNode<T> * GetNodes () { return vFirst;}
private:
ListNode<T> * vFirst;
};
--------------------------------- Template List ends
----------------------------
--------------------------------- Non Template List
-----------------------------
class ListElem
{
public:
virtual ~ListElem (void) {}
ListElem * uNext;
ListElem * uPrev;
};

class MyList
{
public:
MyList () { vFirst = NULL;}
void Insert (ListElem * e) {
e->uNext = vFirst;
e->uPrev = NULL;
if (vFirst != NULL)
vFirst->uPrev = e;
vFirst = e;
}
ListElem * GetNodes () { return vFirst; }
private:
ListElem * vFirst;
};
------------------------------ Non template list ends
--------------------------

Note that the code is *very* similar. I had to derive a ListElem for
the non-template class:
class MyClassElem : public ListElem
{
public:
MyClassElem (MyClass * c) { uMyClass = c; }
MyClass * uMyClass;
};

But didn't have to do anything for the template version.

The cpp test code basically just runs two loops (inserting and
get-ting).

cheers,
/Charles
 
V

Victor Bazarov

Victor said:
[..]
As expected, the std vector is the fastest. However my template list
class is the *slowest*!!! This was definitly not expected.

Does anyone have any inputs on what's going on?

Not really. How can anyone tell anything about the performance of
_your_ program we cannot see, on _your_ computer, without any
ability to measure anything? Are you kidding?

V
Hmmm.... well that's a good point. I couldn't find any way of
uploading my code.

What do you mean?
However, it's pretty small, so I'll just paste it below

It would be best to have all of it, especially to see how you use
your classes and the vector.
----------------------- Template List ----------------------------
template <class T>
class ListNode
{
public:
ListNode (T * pVal) {uVal = pVal;}
T * uVal;
ListNode<T>* uNext;
ListNode<T>* uPrev;

};

template <class T>
class MyTList

That's a misnomer. You might want to call it 'MyTPTRList', since
you're not storing T, but you store pointers to T.

Now, you don't show how you actually fill it up. Are you creating
objects in the free store (using 'new')?
{
public:
MyTList () { vFirst = NULL; }

void Insert (T * e) {
ListNode<T> * ln;
ln = new ListNode<T> (e);
ln->uNext = vFirst;
ln->uPrev = NULL;
if (vFirst != NULL)
vFirst->uPrev = ln;
vFirst = ln;
}
ListNode<T> * GetNodes () { return vFirst;}
private:
ListNode<T> * vFirst;
};
--------------------------------- Template List ends
----------------------------
--------------------------------- Non Template List
-----------------------------
class ListElem
{
public:
virtual ~ListElem (void) {}
ListElem * uNext;
ListElem * uPrev;
};

class MyList
{
public:
MyList () { vFirst = NULL;}
void Insert (ListElem * e) {
e->uNext = vFirst;
e->uPrev = NULL;
if (vFirst != NULL)
vFirst->uPrev = e;
vFirst = e;
}
ListElem * GetNodes () { return vFirst; }
private:
ListElem * vFirst;
};
------------------------------ Non template list ends
--------------------------

Note that the code is *very* similar. I had to derive a ListElem for
the non-template class:
class MyClassElem : public ListElem
{
public:
MyClassElem (MyClass * c) { uMyClass = c; }
MyClass * uMyClass;
};

But didn't have to do anything for the template version.

The cpp test code basically just runs two loops (inserting and
get-ting).

I took your code, derived DoubleListElem from ListElem, and here is
the test driver:

int main()
{
clock_t c0 = clock();

MyTList<double> mtld;
for (int i = 0; i < 1000000; ++i)
mtld.Insert(new double(i));

clock_t c1 = clock();

MyList mld;
for (int i = 0; i < 1000000; ++i)
mld.Insert(new DoubleListElem(new double(i)));

clock_t c2 = clock();

std::cout << "Template: " << c1 - c0 << std::endl;
std::cout << "Nontemplate: " << c2 - c1 << std::endl;
}

The template turned out a tiny bit faster. Now, if you want to
really compare it to the behaviour of 'std::vector', you need to
(a) store values, not pointers, (b) figure out better 'Insert'
strategy, possibly without the 'if'.

Since your code for both template and non-template List is the
same, virtually, there should be essentially no difference (and
there wasn't in my test). What is it you're trying to accomplish?

V
 
C

charles.lobo

Victor said:
Victor said:
(e-mail address removed) wrote:
[..]
As expected, the std vector is the fastest. However my template list
class is the *slowest*!!! This was definitly not expected.

Does anyone have any inputs on what's going on?

Not really. How can anyone tell anything about the performance of
_your_ program we cannot see, on _your_ computer, without any
ability to measure anything? Are you kidding?

V
Hmmm.... well that's a good point. I couldn't find any way of
uploading my code.

What do you mean?
However, it's pretty small, so I'll just paste it below

It would be best to have all of it, especially to see how you use
your classes and the vector.
----------------------- Template List ----------------------------
template <class T>
class ListNode
{
public:
ListNode (T * pVal) {uVal = pVal;}
T * uVal;
ListNode<T>* uNext;
ListNode<T>* uPrev;

};

template <class T>
class MyTList

That's a misnomer. You might want to call it 'MyTPTRList', since
you're not storing T, but you store pointers to T.

Now, you don't show how you actually fill it up. Are you creating
objects in the free store (using 'new')?
{
public:
MyTList () { vFirst = NULL; }

void Insert (T * e) {
ListNode<T> * ln;
ln = new ListNode<T> (e);
ln->uNext = vFirst;
ln->uPrev = NULL;
if (vFirst != NULL)
vFirst->uPrev = ln;
vFirst = ln;
}
ListNode<T> * GetNodes () { return vFirst;}
private:
ListNode<T> * vFirst;
};
--------------------------------- Template List ends
----------------------------
--------------------------------- Non Template List
-----------------------------
class ListElem
{
public:
virtual ~ListElem (void) {}
ListElem * uNext;
ListElem * uPrev;
};

class MyList
{
public:
MyList () { vFirst = NULL;}
void Insert (ListElem * e) {
e->uNext = vFirst;
e->uPrev = NULL;
if (vFirst != NULL)
vFirst->uPrev = e;
vFirst = e;
}
ListElem * GetNodes () { return vFirst; }
private:
ListElem * vFirst;
};
------------------------------ Non template list ends
--------------------------

Note that the code is *very* similar. I had to derive a ListElem for
the non-template class:
class MyClassElem : public ListElem
{
public:
MyClassElem (MyClass * c) { uMyClass = c; }
MyClass * uMyClass;
};

But didn't have to do anything for the template version.

The cpp test code basically just runs two loops (inserting and
get-ting).

I took your code, derived DoubleListElem from ListElem, and here is
the test driver:

int main()
{
clock_t c0 = clock();

MyTList<double> mtld;
for (int i = 0; i < 1000000; ++i)
mtld.Insert(new double(i));

clock_t c1 = clock();

MyList mld;
for (int i = 0; i < 1000000; ++i)
mld.Insert(new DoubleListElem(new double(i)));

clock_t c2 = clock();

std::cout << "Template: " << c1 - c0 << std::endl;
std::cout << "Nontemplate: " << c2 - c1 << std::endl;
}

The template turned out a tiny bit faster. Now, if you want to
really compare it to the behaviour of 'std::vector', you need to
(a) store values, not pointers, (b) figure out better 'Insert'
strategy, possibly without the 'if'.

Since your code for both template and non-template List is the
same, virtually, there should be essentially no difference (and
there wasn't in my test). What is it you're trying to accomplish?

V

Hi,

I tried your program and the template version *is* faster - so I'm
really confused. The rest of my code follows:
--------------------- SImple class MyClass (used as values)
---------------------------
class MyClass
{
public:
MyClass (int i) {uI = i; }
int uI;
};

-------------------- Main that runs a test on Template List
-----------------
void main (int argc, char * argv[])
{
MyTList<MyClass> one;
ListNode<MyClass> * onenode;
long sumone;

for (int i = 0;i < 1000000;i++) {
one.Insert (new MyClass (i));
}

sumone = 0;
onenode = one.GetNodes ();
while (onenode) {
sumone += (onenode->uVal->uI);
onenode = onenode->uNext;
}
}
----------------- Main that runs a test on NonTemplate list
--------------------
void main (int argc, char * argv[])
{
MyList one;
MyClassElem * onenode;
long sumone;

for (int i = 0;i < 1000000;i++) {
one.Insert (new MyClassElem (new MyClass (i)));
}
sumone = 0;
onenode = (MyClassElem*)one.GetNodes ();
while (onenode) {
sumone += onenode->uMyClass->uI;
onenode = (MyClassElem *)onenode->uNext;
}
}
-------------------------- Timer app that runs the above as exes
-----------
void run (char * app)
{
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory (&si, sizeof (si));
si.cb = sizeof (si);
si.lpReserved = NULL;
ZeroMemory (&pi, sizeof (pi));
CreateProcess (NULL, app, NULL, NULL, FALSE, 0, NULL, NULL, &si,
&pi);
WaitForSingleObject (pi.hProcess, INFINITE);
}
void main (int argc, char * argv[])
{
DWORD start;
DWORD diff;
if (argc != 2) {
printf("Usage: timer <program to time>\n");
return;
}
start = GetTickCount ();
run (argv[1]);
diff = GetTickCount () - start;
printf("%d: running %s\n", diff, argv [1]);
}
------------------------------- Code Block Ends
--------------------------------------

What I am trying to do is to check if we can use template-based lists
in our company code. We are currently using lists similar to the
non-template version (with derived classes) and the mandate is that the
template list should have a clear advantage if we've to adopt it.

cheers,
/Charles
 
V

Victor Bazarov

[..]
What I am trying to do is to check if we can use template-based lists
in our company code. We are currently using lists similar to the
non-template version (with derived classes) and the mandate is that
the template list should have a clear advantage if we've to adopt it.

Then stop screwing around and use 'std::list'. And get a book on the
Standard library, preferrably a copy for every programmer on your team
so that nobody is left out trying to figure it out by themselves. I
recommend "Effective" series by Meyers, *all of them*.

V
 
C

charles.lobo

Victor said:
[..]
What I am trying to do is to check if we can use template-based lists
in our company code. We are currently using lists similar to the
non-template version (with derived classes) and the mandate is that
the template list should have a clear advantage if we've to adopt it.

Then stop screwing around and use 'std::list'. And get a book on the
Standard library, preferrably a copy for every programmer on your team
so that nobody is left out trying to figure it out by themselves. I
recommend "Effective" series by Meyers, *all of them*.

V

Sadly I have no chance of selling the usage of std::list without first
proving that templates are not evil. Plus we do not use exceptions in
our code and the overhead of exception usage is not acceptable to our
company. I did try the std::vector (which was bigger but faster).

In any case I'm still not clear why the timing results are different.
Another intersting point is when I changed your code to use "MyClass"
instead of "double" the template list became slower again!

cheers,
/Charles
 
V

Victor Bazarov

Victor said:
[..]
What I am trying to do is to check if we can use template-based
lists in our company code. We are currently using lists similar to
the non-template version (with derived classes) and the mandate is
that the template list should have a clear advantage if we've to
adopt it.

Then stop screwing around and use 'std::list'. And get a book on the
Standard library, preferrably a copy for every programmer on your
team so that nobody is left out trying to figure it out by
themselves. I recommend "Effective" series by Meyers, *all of them*.

V

Sadly I have no chance of selling the usage of std::list without first
proving that templates are not evil.

No offence, but you may not be good enough to prove that. That's what
the books written by experts are for.

Besides, no element of the language is "evil" per se. Just like spoons
do not make anybody fat. It's how you use them. One says, "macros are
evil". I say that I cannot do without them in certain situations. What
am I to do? Go hang myself?
Plus we do not use exceptions in
our code and the overhead of exception usage is not acceptable to our
company. I did try the std::vector (which was bigger but faster).

Bigger but faster on what operations? And what relation does 'vector'
have to "no exceptions" policy of your company? It does throw, if you
must know.
In any case I'm still not clear why the timing results are different.
Another intersting point is when I changed your code to use "MyClass"
instead of "double" the template list became slower again!

So what? Performance is a characteristic of an entire application.
It cannot be deduced from the techniques used or from the language in
which the application is written (obvious cases aside). It can only
be *measured*. If your company is concerned with performance, you need
to use tools to figure out what part of your application is slow and
why, and what to do about it. Don't guess [that templates are going to
solve all your problems]. Only use certain elements of the language if
you see that there is no moving forward without them.

You can always improve the performance of some code by either reducing
the amount of [unnecessary] work it's doing or by sacrificing something
else, like memory footprint. Does it have to involve templates? No.
Do templates help? Not really. It's not what they are for.

The bottomline: learn the language, learn what different elements are
for, and use them as appropriate. But FCOL, learn the language!

V
 
P

peter koch

(e-mail address removed) skrev:
Victor said:
[..]
What I am trying to do is to check if we can use template-based lists
in our company code. We are currently using lists similar to the
non-template version (with derived classes) and the mandate is that
the template list should have a clear advantage if we've to adopt it.

Then stop screwing around and use 'std::list'. And get a book on the
Standard library, preferrably a copy for every programmer on your team
so that nobody is left out trying to figure it out by themselves. I
recommend "Effective" series by Meyers, *all of them*.

V

Sadly I have no chance of selling the usage of std::list without first
proving that templates are not evil. Plus we do not use exceptions in
our code and the overhead of exception usage is not acceptable to our
company.

What overhead? Unless you write quite specialised code, the overhead of
exceptionhandling is certainly acceptable. As I assume that your
company does try to do some errorhandling, the overhead of
exception-handling is not just something you pay for. You do also get
something in return - namely no longer needing to continuously check
return codes.
This is not just a programmer convenience. It is also far less code,
far less clutter and faster programs, but most importantly it's
increased reliability since you are no longer as likely to overlook
missing return code checks. I can tell you, as I right now work for a
company with the same exception policy (no exceptions!) as in your
company, and our codebase does have places where errorcodes are not
checked (and potential resource leaks because the style and the age of
the code means that to many raw allocations are made and not always
freed after use). The problem with my company is not only that there is
a distrust in exceptions (probably for the same silly reasons that your
company has) and that our codebase is very large (20000 sourcefiles on
the project I am working on), so I can see some raison in not changing
policy. Unfortunately the same reasoning might very well result in
throwing C++ out the window. No new projects are - to my knowledge -
started in C++ today, and who can really blame that considering the
mess they have brought them self into.

/Peter
 
C

charles.lobo

Victor said:
Victor said:
(e-mail address removed) wrote:
[..]
What I am trying to do is to check if we can use template-based
lists in our company code. We are currently using lists similar to
the non-template version (with derived classes) and the mandate is
that the template list should have a clear advantage if we've to
adopt it.

Then stop screwing around and use 'std::list'. And get a book on the
Standard library, preferrably a copy for every programmer on your
team so that nobody is left out trying to figure it out by
themselves. I recommend "Effective" series by Meyers, *all of them*.

V

Sadly I have no chance of selling the usage of std::list without first
proving that templates are not evil.

No offence, but you may not be good enough to prove that. That's what
the books written by experts are for.
It's true I'm not an expert but I would still like to understand the
language elements I am using. Performance is a key factor in our
company and it's natural for me to try and understand how a feature
like templates would affect it before recommending it's use.
I have started to read "Effective C++" by Scott. It's *excellent*
(thanks for the reco) but it doesn't give me anything much about
performance of templates. Maybe that's because there isn't enough
benchmarks yet or because templates don't have a consistent affect on
performance (??).
I've also read the latest "Technical Report on C++ Performance ISO/IEC
TR 18015:2006(E)" where I picked up that templates <quote>can lead to
an unexpectedly large amount of code and data. said:
Besides, no element of the language is "evil" per se. Just like spoons
do not make anybody fat. It's how you use them. One says, "macros are
evil". I say that I cannot do without them in certain situations. What
am I to do? Go hang myself?


Bigger but faster on what operations? And what relation does 'vector'
have to "no exceptions" policy of your company? It does throw, if you
must know.
Yes I do know (I have to enable exception sematics while compiling).
It's bigger and faster on the same test case (inserting 1000000
elements and accessing them). The reason I can't recommend it's usage
is simply because it requires exception support.
In any case I'm still not clear why the timing results are different.
Another intersting point is when I changed your code to use "MyClass"
instead of "double" the template list became slower again!

So what? Performance is a characteristic of an entire application.
It cannot be deduced from the techniques used or from the language in
which the application is written (obvious cases aside). It can only
be *measured*. If your company is concerned with performance, you need
to use tools to figure out what part of your application is slow and
why, and what to do about it. Don't guess [that templates are going to
solve all your problems]. Only use certain elements of the language if
you see that there is no moving forward without them.
We do use several tools to measure performance. However, the philosophy
of the company is that the way to good performance is for each
subsystem to squeeze out the best possible performance. This is
especially true for "basic" elements like the list and we have several
high-quality basic elements (like lists, synchronization primitives,
memory managers, etc). The lists are, however, inheritance based so I
wanted to convert to template based because I read that templates were
recommended for containers.
Of course the idea that if everything is high performance, the product
will be high performance is not entirely true (which is why we use
profilers to find bottlenecks), but it does work very well in practice.
Our products are small and _fast_.
I did try looking at some good open source projects (apache httpd and
bekeley db) to see if they use templates but they don't. So maybe I'm
on a sticky wicket here.
You can always improve the performance of some code by either reducing
the amount of [unnecessary] work it's doing or by sacrificing something
else, like memory footprint. Does it have to involve templates? No.
Do templates help? Not really. It's not what they are for.
The holy grail we look for is to improve both speed *and* resource
usage without sacrificing features. It's one of our key
differentiators. It's not easy to do but it's possible.
What really interested me, though, was that while whatever I read
seemed to say that using templates would make your code bigger but
faster, in this simple example templates are smaller and slower!
The bottomline: learn the language, learn what different elements are
for, and use them as appropriate. But FCOL, learn the language!
I will :). Thanks for your inputs and help so far.
 
C

charles.lobo

peter said:
(e-mail address removed) skrev:
Victor said:
(e-mail address removed) wrote:
[..]
What I am trying to do is to check if we can use template-based lists
in our company code. We are currently using lists similar to the
non-template version (with derived classes) and the mandate is that
the template list should have a clear advantage if we've to adopt it.

Then stop screwing around and use 'std::list'. And get a book on the
Standard library, preferrably a copy for every programmer on your team
so that nobody is left out trying to figure it out by themselves. I
recommend "Effective" series by Meyers, *all of them*.

V

Sadly I have no chance of selling the usage of std::list without first
proving that templates are not evil. Plus we do not use exceptions in
our code and the overhead of exception usage is not acceptable to our
company.

What overhead? Unless you write quite specialised code, the overhead of
exceptionhandling is certainly acceptable. As I assume that your
company does try to do some errorhandling, the overhead of
exception-handling is not just something you pay for. You do also get
something in return - namely no longer needing to continuously check
return codes.
This is not just a programmer convenience. It is also far less code,
far less clutter and faster programs, but most importantly it's
increased reliability since you are no longer as likely to overlook
missing return code checks. I can tell you, as I right now work for a
company with the same exception policy (no exceptions!) as in your
company, and our codebase does have places where errorcodes are not
checked (and potential resource leaks because the style and the age of
the code means that to many raw allocations are made and not always
freed after use). The problem with my company is not only that there is
a distrust in exceptions (probably for the same silly reasons that your
company has) and that our codebase is very large (20000 sourcefiles on
the project I am working on), so I can see some raison in not changing
policy. Unfortunately the same reasoning might very well result in
throwing C++ out the window. No new projects are - to my knowledge -
started in C++ today, and who can really blame that considering the
mess they have brought them self into.

/Peter
Exception handling does have *significant* peformance overhead.
<quote>Compared to a normal function return, returning from a function
by throwing an exception may be as much as three orders of magnitude
(!) slower</quote>. Even though you may incur this cost rarely
(depending on how you use exceptions), there is still potential code
bloat and a performance hit.
We use assertions quite generously (which reduces the number of error
returns drastically) and that works very well. We have no
memory/resource leaks (in our codebase of 3500 files - not nearly as
large as yours) and we do check for return codes everywhere.
IMHO exceptions aren't that great anyway (also see
http://www.joelonsoftware.com/items/2003/10/13.html) because they don't
mandate who deals with them (i.e. there is no ownership of errors). In
the return code world the caller *must* deal with the error conditions.
In the exception world, he can ignore it to the peril of functions
higher up in the chain.
Having said that, exceptions could be useful for simple, or business
oriented programs where performance isn't a major factor (like much of
Java code). Or maybe we need to think up a different paradigm for error
handling altogether....
 
?

=?iso-8859-1?q?Kirit_S=E6lensminde?=

peter said:
(e-mail address removed) skrev:
Victor Bazarov wrote:
(e-mail address removed) wrote:
[..]
What I am trying to do is to check if we can use template-based lists
in our company code. We are currently using lists similar to the
non-template version (with derived classes) and the mandate is that
the template list should have a clear advantage if we've to adopt it.

Then stop screwing around and use 'std::list'. And get a book on the
Standard library, preferrably a copy for every programmer on your team
so that nobody is left out trying to figure it out by themselves. I
recommend "Effective" series by Meyers, *all of them*.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Sadly I have no chance of selling the usage of std::list without first
proving that templates are not evil. Plus we do not use exceptions in
our code and the overhead of exception usage is not acceptable to our
company.

What overhead? Unless you write quite specialised code, the overhead of
exceptionhandling is certainly acceptable. As I assume that your
company does try to do some errorhandling, the overhead of
exception-handling is not just something you pay for. You do also get
something in return - namely no longer needing to continuously check
return codes.
This is not just a programmer convenience. It is also far less code,
far less clutter and faster programs, but most importantly it's
increased reliability since you are no longer as likely to overlook
missing return code checks. I can tell you, as I right now work for a
company with the same exception policy (no exceptions!) as in your
company, and our codebase does have places where errorcodes are not
checked (and potential resource leaks because the style and the age of
the code means that to many raw allocations are made and not always
freed after use). The problem with my company is not only that there is
a distrust in exceptions (probably for the same silly reasons that your
company has) and that our codebase is very large (20000 sourcefiles on
the project I am working on), so I can see some raison in not changing
policy. Unfortunately the same reasoning might very well result in
throwing C++ out the window. No new projects are - to my knowledge -
started in C++ today, and who can really blame that considering the
mess they have brought them self into.

/Peter
Exception handling does have *significant* peformance overhead.
<quote>Compared to a normal function return, returning from a function
by throwing an exception may be as much as three orders of magnitude
(!) slower</quote>. Even though you may incur this cost rarely
(depending on how you use exceptions), there is still potential code
bloat and a performance hit.
We use assertions quite generously (which reduces the number of error
returns drastically) and that works very well. We have no
memory/resource leaks (in our codebase of 3500 files - not nearly as
large as yours) and we do check for return codes everywhere.
IMHO exceptions aren't that great anyway (also see
http://www.joelonsoftware.com/items/2003/10/13.html) because they don't
mandate who deals with them (i.e. there is no ownership of errors). In
the return code world the caller *must* deal with the error conditions.
In the exception world, he can ignore it to the peril of functions
higher up in the chain.
Having said that, exceptions could be useful for simple, or business
oriented programs where performance isn't a major factor (like much of
Java code). Or maybe we need to think up a different paradigm for error
handling altogether....

Joel is right about all sorts of things, but he isn't right about
everything. There are contexts within which exceptions are a pain and
places where their use makes no sense or complicates code. But that
isn't the same as saying that they are never the best way of dealing
with a situations.

His two arguments are easily put in perspective though:

"They are invisible in the source code": For the first take a look at
http://www.kirit.com/Handling COM errors in C++ on my site
which explores this issue in the context of COM error handling. The
sample code that Microsoft used is buggy precisely because they nest if
statements to handle error conditions. Yes the error checking
statements are clearly visible and that is exactly the problem - they
obscure the flow to such an extent that they themselves become a source
of problems.

"They create too many possible exit points": Joel's second point is
true if you are manually handling resources (i.e. you have to manually
free the resources). Then the extra exit points are an important
consideration. If you're using RIAA then this is a non-issue. And if
you're not using RIAA then you're not really using C++ IMHO.


K
 
C

charles.lobo

Kirit said:
peter said:
(e-mail address removed) skrev:
Victor Bazarov wrote:
(e-mail address removed) wrote:
[..]
What I am trying to do is to check if we can use template-based lists
in our company code. We are currently using lists similar to the
non-template version (with derived classes) and the mandate is that
the template list should have a clear advantage if we've to adopt it.

Then stop screwing around and use 'std::list'. And get a book on the
Standard library, preferrably a copy for every programmer on your team
so that nobody is left out trying to figure it out by themselves. I
recommend "Effective" series by Meyers, *all of them*.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Sadly I have no chance of selling the usage of std::list without first
proving that templates are not evil. Plus we do not use exceptions in
our code and the overhead of exception usage is not acceptable to our
company.

What overhead? Unless you write quite specialised code, the overhead of
exceptionhandling is certainly acceptable. As I assume that your
company does try to do some errorhandling, the overhead of
exception-handling is not just something you pay for. You do also get
something in return - namely no longer needing to continuously check
return codes.
This is not just a programmer convenience. It is also far less code,
far less clutter and faster programs, but most importantly it's
increased reliability since you are no longer as likely to overlook
missing return code checks. I can tell you, as I right now work for a
company with the same exception policy (no exceptions!) as in your
company, and our codebase does have places where errorcodes are not
checked (and potential resource leaks because the style and the age of
the code means that to many raw allocations are made and not always
freed after use). The problem with my company is not only that there is
a distrust in exceptions (probably for the same silly reasons that your
company has) and that our codebase is very large (20000 sourcefiles on
the project I am working on), so I can see some raison in not changing
policy. Unfortunately the same reasoning might very well result in
throwing C++ out the window. No new projects are - to my knowledge -
started in C++ today, and who can really blame that considering the
mess they have brought them self into.

/Peter
Exception handling does have *significant* peformance overhead.
<quote>Compared to a normal function return, returning from a function
by throwing an exception may be as much as three orders of magnitude
(!) slower</quote>. Even though you may incur this cost rarely
(depending on how you use exceptions), there is still potential code
bloat and a performance hit.
We use assertions quite generously (which reduces the number of error
returns drastically) and that works very well. We have no
memory/resource leaks (in our codebase of 3500 files - not nearly as
large as yours) and we do check for return codes everywhere.
IMHO exceptions aren't that great anyway (also see
http://www.joelonsoftware.com/items/2003/10/13.html) because they don't
mandate who deals with them (i.e. there is no ownership of errors). In
the return code world the caller *must* deal with the error conditions.
In the exception world, he can ignore it to the peril of functions
higher up in the chain.
Having said that, exceptions could be useful for simple, or business
oriented programs where performance isn't a major factor (like much of
Java code). Or maybe we need to think up a different paradigm for error
handling altogether....

Joel is right about all sorts of things, but he isn't right about
everything. There are contexts within which exceptions are a pain and
places where their use makes no sense or complicates code. But that
isn't the same as saying that they are never the best way of dealing
with a situations.

His two arguments are easily put in perspective though:

"They are invisible in the source code": For the first take a look at
http://www.kirit.com/Handling COM errors in C++ on my site
which explores this issue in the context of COM error handling. The
sample code that Microsoft used is buggy precisely because they nest if
statements to handle error conditions. Yes the error checking
statements are clearly visible and that is exactly the problem - they
obscure the flow to such an extent that they themselves become a source
of problems.

"They create too many possible exit points": Joel's second point is
true if you are manually handling resources (i.e. you have to manually
free the resources). Then the extra exit points are an important
consideration. If you're using RIAA then this is a non-issue. And if
you're not using RIAA then you're not really using C++ IMHO.


K
You're argument is perfectly valid - not using exceptions does make the
code less readable and potentially more buggy. The flip side is that
not using exeption also makes the code more efficient. So if you're
willing to pay the price (which we are) of strict reviews/inspections
and a host of automated unit tests it may still not be worth the
overhead of exceptions.
Microsoft code is not a good example in any case. I've been looking at
good open source projects (apache and berkelydb) and they don't use
exceptions or templates. And their code quality is excellent without
paying the price of any overhead. Microsoft's code is both buggy and
bloated - really not the best of examples. :) :)
 
C

charles.lobo

Kirit said:
peter said:
(e-mail address removed) skrev:
Victor Bazarov wrote:
(e-mail address removed) wrote:
[..]
What I am trying to do is to check if we can use template-based lists
in our company code. We are currently using lists similar to the
non-template version (with derived classes) and the mandate is that
the template list should have a clear advantage if we've to adopt it.

Then stop screwing around and use 'std::list'. And get a book on the
Standard library, preferrably a copy for every programmer on your team
so that nobody is left out trying to figure it out by themselves. I
recommend "Effective" series by Meyers, *all of them*.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Sadly I have no chance of selling the usage of std::list without first
proving that templates are not evil. Plus we do not use exceptions in
our code and the overhead of exception usage is not acceptable to our
company.

What overhead? Unless you write quite specialised code, the overhead of
exceptionhandling is certainly acceptable. As I assume that your
company does try to do some errorhandling, the overhead of
exception-handling is not just something you pay for. You do also get
something in return - namely no longer needing to continuously check
return codes.
This is not just a programmer convenience. It is also far less code,
far less clutter and faster programs, but most importantly it's
increased reliability since you are no longer as likely to overlook
missing return code checks. I can tell you, as I right now work for a
company with the same exception policy (no exceptions!) as in your
company, and our codebase does have places where errorcodes are not
checked (and potential resource leaks because the style and the age of
the code means that to many raw allocations are made and not always
freed after use). The problem with my company is not only that there is
a distrust in exceptions (probably for the same silly reasons that your
company has) and that our codebase is very large (20000 sourcefiles on
the project I am working on), so I can see some raison in not changing
policy. Unfortunately the same reasoning might very well result in
throwing C++ out the window. No new projects are - to my knowledge -
started in C++ today, and who can really blame that considering the
mess they have brought them self into.

/Peter
Exception handling does have *significant* peformance overhead.
<quote>Compared to a normal function return, returning from a function
by throwing an exception may be as much as three orders of magnitude
(!) slower</quote>. Even though you may incur this cost rarely
(depending on how you use exceptions), there is still potential code
bloat and a performance hit.
We use assertions quite generously (which reduces the number of error
returns drastically) and that works very well. We have no
memory/resource leaks (in our codebase of 3500 files - not nearly as
large as yours) and we do check for return codes everywhere.
IMHO exceptions aren't that great anyway (also see
http://www.joelonsoftware.com/items/2003/10/13.html) because they don't
mandate who deals with them (i.e. there is no ownership of errors). In
the return code world the caller *must* deal with the error conditions.
In the exception world, he can ignore it to the peril of functions
higher up in the chain.
Having said that, exceptions could be useful for simple, or business
oriented programs where performance isn't a major factor (like much of
Java code). Or maybe we need to think up a different paradigm for error
handling altogether....

Joel is right about all sorts of things, but he isn't right about
everything. There are contexts within which exceptions are a pain and
places where their use makes no sense or complicates code. But that
isn't the same as saying that they are never the best way of dealing
with a situations.

His two arguments are easily put in perspective though:

"They are invisible in the source code": For the first take a look at
http://www.kirit.com/Handling COM errors in C++ on my site
which explores this issue in the context of COM error handling. The
sample code that Microsoft used is buggy precisely because they nest if
statements to handle error conditions. Yes the error checking
statements are clearly visible and that is exactly the problem - they
obscure the flow to such an extent that they themselves become a source
of problems.

"They create too many possible exit points": Joel's second point is
true if you are manually handling resources (i.e. you have to manually
free the resources). Then the extra exit points are an important
consideration. If you're using RIAA then this is a non-issue. And if
you're not using RIAA then you're not really using C++ IMHO.


K
[OFF TOPIC]
Nice article btw - I liked the fonts and layout. Just curious - do you
hand code your site it or is use some program?
[/OFF TOPIC]
 
A

ajalkane

Microsoft code is not a good example in any case. I've been looking at
good open source projects (apache and berkelydb) and they don't use
exceptions or templates.

Do you think this might have something to do with both of those
projects being written in C and not C++? It's hard to use
exceptions or templates if the language has no support for them.
 
I

Ian Collins

You're argument is perfectly valid - not using exceptions does make the
code less readable and potentially more buggy. The flip side is that
not using exeption also makes the code more efficient. So if you're
willing to pay the price (which we are) of strict reviews/inspections
and a host of automated unit tests it may still not be worth the
overhead of exceptions.

Nonsense. If exceptions are used as designed, for exception conditions,
the reverse is often true. All those conditionals add more overhead to
the normal program flow than exceptions.
 
I

Ian Collins

Exception handling does have *significant* peformance overhead.
<quote>Compared to a normal function return, returning from a function
by throwing an exception may be as much as three orders of magnitude
(!) slower</quote>. Even though you may incur this cost rarely
(depending on how you use exceptions), there is still potential code
bloat and a performance hit.

For that to be true, the exception condition would have to occur once
every 1000 calls or less. In which case, is it truly an exception
condition?
We use assertions quite generously (which reduces the number of error
returns drastically) and that works very well. We have no
memory/resource leaks (in our codebase of 3500 files - not nearly as
large as yours) and we do check for return codes everywhere.
IMHO exceptions aren't that great anyway (also see
http://www.joelonsoftware.com/items/2003/10/13.html) because they don't
mandate who deals with them (i.e. there is no ownership of errors). In
the return code world the caller *must* deal with the error conditions.

And if it can't? It passes another error condition back to its caller.
May as well let the run time take care of this, which is what
exceptions do.
In the exception world, he can ignore it to the peril of functions
higher up in the chain.
Having said that, exceptions could be useful for simple, or business
oriented programs where performance isn't a major factor (like much of
Java code). Or maybe we need to think up a different paradigm for error
handling altogether....
You have to differentiate between errors and exception conditions. If
there is a reasonable probability an operation will fail, return an
error. If not, throw and exception.
 
C

charles.lobo

Do you think this might have something to do with both of those
projects being written in C and not C++? It's hard to use
exceptions or templates if the language has no support for them.
Berkely DB has a C++ version. I just re-checked and the do provide
support (optional) for exceptions, though they do not use templates.
The exception support also can be "turned off".
Could you point me (genuinely) to a powerful project that does use
modern C++? I have been looking but haven't been too successful yet.
Adobe uses the boost library somewhere, but adobe is *so* slow to load
it's a bad example for me. So I'm still looking.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,608
Members
45,244
Latest member
cryptotaxsoftware12

Latest Threads

Top