LWN.net Logo

Sometimes C++ is faster

Sometimes C++ is faster

Posted Jun 18, 2008 15:23 UTC (Wed) by seanyoung (subscriber, #28711)
Parent article: Converting GCC to C++

I don't want to be dogmatic about this, but I do admit a great affinity for plain C. Things
like templates might very well be a good thing.

However, whenever I read statements like "Sometimes C++ is faster" I just don't get it. What
can C++ do which produces faster code? What am I missing?


(Log in to post comments)

Sometimes C++ is faster

Posted Jun 18, 2008 15:31 UTC (Wed) by johnkarp (guest, #39285) [Link]

IIRC, if you need inheritance and virtual functions, its much faster to 
use C++'s builtins rather than to kludge your own in C. Also, the C 
standard library string functions can be pretty inefficient.

Virtual functions have the same speed

Posted Jun 18, 2008 20:54 UTC (Wed) by khim (subscriber, #9252) [Link]

Remember - for a long, long time C++ compiler was C++-to-C compiler. Only one thing can not be efficiently implemented in C++-to-C compiler: exceptions. Everything else is just as efficient in C and in C++... except templates: where C++ compiler can generate series of functions automatically in C you either need horrible preprocessor cludges and/or code duplication.

Of course the same capability can be easily abused and lead to slower code!

Virtual functions have the same speed

Posted Jun 19, 2008 9:48 UTC (Thu) by nix (subscriber, #2304) [Link]

For a long, long time? I think the gap was something like three years between Cfront and G++.
It might have felt like a long time then, but it really wasn't. :)

10 years is long time in computing

Posted Jun 19, 2008 14:04 UTC (Thu) by khim (subscriber, #9252) [Link]

Cfront defined C++ for almost 10 years. Between 1983 and 1993 Cfront was the C++ compiler - and a lot of limitations of C++ back then were justified by the need to compile to C. It was reference implementation, it was used to define "standard C++" (people even used versions of Cfront to explain what type of language their compiler supported), etc. Eventually Cfront 4.0 was abandoned and after long period of instability (~5years) we've got consolidated standard and language was set in stone. But yes, for a long time needs of C++-to-C compiler defined the language.

Sometimes C++ is faster

Posted Jun 19, 2008 9:34 UTC (Thu) by cate (subscriber, #1359) [Link]

virtual function are a lot slower than the direct C equivalent. Because of class expandability
and multiple heritage, the virtual table is not put together data, but accessed with an
additional pointer. So to call a virtual function CPU will use two pointers, which is cache
and pre-fetch inefficient.

Ideally a C++ optimized (program level, not unit level) should know if a class is expanded and
it should allocates some part of virtual table together to the data. (maybe there is also a
pragma directive). So in this trade-off, c++ chooses the slower but more expandable method.

Anyway I think he said faster, because the STL are optimized (probably ugly code, but well
tested and anyway not mixed with program), which is not the case of normal c++ programming.
But we speak about compiler developers, which should know very well C++ and ugly optimization,
so for GCC I don't think STL will give significant improvements.

C++ has also linker problem: dynamic linking is a lot slower (number of function, but also
because long names, which differentiate only at the end)

IMHO the readability, extendibility of code is better that fast code (but for gentoo users
;-)).

Sometimes C++ is faster

Posted Jun 19, 2008 10:01 UTC (Thu) by nix (subscriber, #2304) [Link]

My understanding is that what you say is true in modern compilers only for virtual functions
defined in virtual base classes. Non-virtual-base class virtual function lookup requires only
a single pointer dereference, from a fixed offset in the VMT, as does lookup of a virtual
function defined in a class that has virtual bases, but not itself defined in that virtual
base class or one of its ancestors.

Virtual base classes are rare. This is one reason why. (Another reason is that, well, the
designs that require virtual bases are generally either involuted or icky.)

Sometimes C++ is faster

Posted Jun 19, 2008 11:53 UTC (Thu) by cate (subscriber, #1359) [Link]

I'm not so sure that I understand your comment. My concern is about where compilers put the
VMT table. If it is split from the data (as my (old) understanding and as I see in wikipedia),
every class requires a pointer to the VMT, so there is two dereferences.

The solution was to put some part (i.e. the first 10 virtual function pointer) into the class
data, but because it cause more memory demand (i.e. event driven programming), I don't think
it is default.

Thus I like the C++ idea, if it bring to more development, especially on the optimization at
program level (and not only at unit level).

Sometimes C++ is faster

Posted Jun 19, 2008 18:06 UTC (Thu) by nix (subscriber, #2304) [Link]

Oh, yeah, you have to jump to the VMT first, so two dereferences it is. 
Sometimes there are *more* than two, though (and sometimes there are none, 
as when the compiler can determine the static type of the instance: this 
happens more often than you might expect).

Usually C++ is faster

Posted Jun 19, 2008 18:39 UTC (Thu) by ncm (subscriber, #165) [Link]

Lots of falsehoods, misconceptions, and old myths to fix here.

First, the STL containers and algorithms don't use virtual functions at all.  Virtual
functions aren't used much in modern C++ code, particularly in places where it matters how
fast they are or aren't.  This isn't so much because people worry much about how fast they
are, but just because they are not often especially useful in low-level code where speed
matters.

Second, whatever overhead is associated with a virtual function call has very little to do
with how many memory accesses occur, and everything to do with pipeline stalls.  If the speed
of a virtual function call matters, it's in a loop, and all the relevant memory is in cache.
You might lose a cycle or two loading a memory word, then, but you lose a dozen or two
branching through a pointer because the execution pipeline can't look ahead past that branch.
If you used a function pointer in C, you would suffer precisely the same stall.   (There are
further complications I won't get into here.)

So, as rules of thumb: (1) if it matters how fast a virtual function call is, compared to a
regular function call, you're probably doing it wrong; and (2) a virtual function call is
architecturally equivalent to calling through a C function pointer.  How much do you use
function pointers in C?  That's about how much you should use virtual functions in C++.  (If
you're more used to Java... may heaven grant mercy on your soul.)

In practice, the time spent doing virtual function calls has no measurable effect on the speed
of a well-conceived C++ program.

Sometimes C++ is faster

Posted Jun 19, 2008 15:20 UTC (Thu) by endecotp (guest, #36428) [Link]

What you say is true, but it's mitigated in a few ways:

- None of this matters if the actual class of the object is known.  It only matters if you're
accessing a derived class via a base class pointer.

- If you're accessing several virtual members, the dereference to get the virtual function
table only needs to be done once.

- Virtual methods are rare in C++ (compared to e.g. Java).  I don't believe there are any at
all in the standard library, for example.

- Using less memory per object will improve your cache hit rate when you have more than a few
objects.


Here's a C++ benchmark.  "----" indicates a new file, to prevent too much being optimised
away:

struct base {
  virtual void foo() = 0;
};

struct derived: public base {
  void foo() {
    f1();
  }
};

----

int main()
{
  for (int i=0; i<100000000; ++i) {
    base* p = f2();
    p->foo();
  }
}

----

void f1() {
}

base* f2() {
  static derived d;
  return &d;
}


And here's a C version (well, actually it's still C++ but it's using a function pointer in the
struct rather than a virtual function):

struct base {
  typedef void(*foo_t)();
  const foo_t foo;

  base(foo_t f_): foo(f_) {}
};

----

int main()  // same as C++ version
{
  for (int i=0; i<100000000; ++i) {
    base* p = f2();
    p->foo();
  }
}

----

void f1() {
}

struct derived: public base {
  derived(): base(&f1) {}
};

base* f2() {
  static derived d;
  return &d;
}


Comparing these programs (x86, gcc 4.3.1, -O3) I find that the "C" version is about 20%
faster, or around 6 nanoseconds per call, on this 1 GHz VIA C3 machine.  That fraction would
clearly drop if you actually did something inside the virtual function.

Sometimes C++ is faster

Posted Jun 26, 2008 12:45 UTC (Thu) by tbrownaw (guest, #45457) [Link]

- Virtual methods are rare in C++ (compared to e.g. Java). I don't believe there are any at
all in the standard library, for example.
std::streambuf::xs{get,put}n and several other protected streambuf functions. Not something you'll usually work with directly, but used by all the i/o streams.

Sometimes C++ is faster

Posted Jun 19, 2008 21:03 UTC (Thu) by pynm0001 (guest, #18379) [Link]

> virtual function are a lot slower than the direct C equivalent.

How would you do in C then?  Because however it is, it can be done that way in C++.

More seriously though, you are saying that C++ does something like:

this->v_btl->virtual_call(params); right?

I would agree, but how would you do this any faster in C?  Recognize that you may not cast the
object pointer to a derived class, the compiler can't (necessarily) know that the conversion
is valid, and you could cast it in C++ if the programmer happens to know more than the
compiler.

i.e. if you were to do:

derived_virtual_impl(klass, params) in C, you could do:

obj->Derived::impl(params) in C++ and call the appropriate implementation directly.

Is there some neat-o technique I'm missing?

Sometimes C++ is faster

Posted Jun 19, 2008 21:10 UTC (Thu) by pynm0001 (guest, #18379) [Link]

Sorry about replying twice but I missed this one too:

> C++ has also linker problem: dynamic linking is a lot slower (number of 
> function, but also because long names, which differentiate only at the
> end)

This is annoyingly true.  However, this has pretty much been rectified.

With recent binutils (I think 2.17.50 or later?) a new hash table format is used for ELF
dynamic binaries which significantly reduces the amount of string comparisons that must be
done in order to properly load a symbol.  Of course long symbol names still take a while to
load so it is important to reduce the amount of symbols used to the minimum necessary.  If you
have recent binutils you may already be able to see the fruits of this, you can use readelf -d
to see if you have a GNU_HASH section of a binary or a .so.

g++ since 4.0 has supported visibility for symbols, including symbols defined as part of C++
class and template generation, which takes care of that problem.  The problem is that C++
libraries must specifically support it, but support for that is growing.

prelinking provides benefits on top of that.  There are patches from Michael Meeks floating
around to allow a flag called -Bsymbolic which apparently also helps, but I don't really know
what it does beyond that, and it does not look like it will make it into binutils anyways.

But there's lots of work being done to rectify these problems, so it lookslike we're *almost*
getting to the point to where we can have our cake and eat it too. :)

Sometimes C++ is faster

Posted Jun 18, 2008 15:38 UTC (Wed) by tetromino (subscriber, #33846) [Link]

For many functions that are both in glibc and g++'s STL, the STL version is faster.

Sometimes C++ is faster

Posted Jun 18, 2008 16:55 UTC (Wed) by jengelh (subscriber, #33263) [Link]

This was not true for GNU's stdlibc++3.3. Thankfully they fixed it.

Sometimes C++ is faster

Posted Jun 18, 2008 15:59 UTC (Wed) by hans (subscriber, #148) [Link]

I agree with the other responses, and I'll add a concrete example:  qsort.  The qsort function
that is in the standard C library takes a void pointer and a callback as a parameter so that
the same algorithm can be used for multiple types.  The void pointer can point to an array of
chars, ints, etc. and the callback is used to compare two members of the array.  But that
callback adds overhead, which often leads developers to hand-code a quicksort function for
each type as an optimization.

In the C++ Standard Template Library, there is also a sort function, but since it uses
templates, the algorithm can be used regardless of the underlying type.  So the C++ compiler
can optimize the template-based sort to be as efficient as the hand-coded function.  Or that's
the theory, anyway.

Sometimes C++ is faster

Posted Jun 18, 2008 16:06 UTC (Wed) by endecotp (guest, #36428) [Link]

Try this:

http://theory.stanford.edu/~amitp/rants/c++-vs-c/

for numbers supporting this analysis.

Sometimes C++ is faster

Posted Jun 18, 2008 17:00 UTC (Wed) by rompel (subscriber, #4512) [Link]

Of course you could implement qsort as a C macro and get the same advantage. See here for example. No doubt the template implementation is cleaner, but not all that much. Once again, C++ provides some nice syntactic sugar, but no fundamental advantage.

Sometimes C++ is faster

Posted Jun 18, 2008 17:06 UTC (Wed) by epa (subscriber, #39769) [Link]

However, do you really fancy writing all of your algorithms as macros?  Of course impressive
hacks are possible as one-offs.

Sometimes C++ is faster

Posted Jun 19, 2008 7:16 UTC (Thu) by eric.rannaud (guest, #44292) [Link]

It is not really a one time feat: OpenSSL has a good example of this for
type-checked hash tables: see lhash(3ssl) or
http://www.openssl.org/docs/crypto/lhash.html

Sometimes C++ is faster

Posted Jun 18, 2008 17:36 UTC (Wed) by pphaneuf (subscriber, #23480) [Link]

One problem with this (among others) is that it becomes very hard to debug. For example, any issue inside the macro gets reported on the line number that invoked it.

Sometimes C++ is faster

Posted Jun 18, 2008 18:11 UTC (Wed) by gnb (subscriber, #5132) [Link]

True, but compilation errors in C++ template use (the alternative being 
considered here) frequently aren't models of clarity either. 

Sometimes C++ is faster

Posted Jun 18, 2008 21:04 UTC (Wed) by pphaneuf (subscriber, #23480) [Link]

Right, but I'll take too much information over too little any given day.

It's kind of funny, but there are filters you can use to make those more readable. I think they're integrating some of these changes in GCC? Or maybe the diagnostic messages mandated in C++0x are going to be better, I don't remember...

C++0x to save the day

Posted Jun 18, 2008 21:21 UTC (Wed) by ncm (subscriber, #165) [Link]

C++0x, the next Standard C++, will support "concepts", whose chief benefit is to allow library
writers to make the compiler produce comprehensible error messages for library usage errors.
Therefore, this problem is temporary.

C++0x to save the day

Posted Jun 18, 2008 22:03 UTC (Wed) by ajross (subscriber, #4563) [Link]

This is a joke, right?  The solution to "this language's error messages suck" is "make it the
library author's job to fix it".  I await such a feature with baited breath.  Truly, this will
revolutionize programming.  Just think about how we've all been suffering in modern languages
with their readable and non-configurable errors!  Woe!

Pathetic.  I'm sorry, but C++ has jumped the shark at this point.  The language is now
self-parody.  It appeals not to productive hackers, but to gadget freaks and language theory
nerds.

And yeah, the snark is flowing freely in this post.  But I stand by every word of it.

C++0x to save the day

Posted Jun 18, 2008 22:28 UTC (Wed) by pphaneuf (subscriber, #23480) [Link]

This is because template parameters are untyped (they are types themselves!), and concepts are basically typing for types. C preprocessor macros have exactly the same problem. Consider this:

#include <stdio.h>

// Ignore that this is unsafe, it's just an example.
#define mymacro(X) printf(X)

void main() {
    mymacro(42);
}

You can see that there is no typing for X there, and the same applies to template parameters (except they actually do have a little bit of typing, but not much).

Also, you might note that in C, this compiles with a warning, then crashes at runtime. In C++, compile-time error, because, well, it is. That's an example of what I was saying earlier: program in C, but call your file foo.cc instead of foo.c, and it will be better. You won't get any of those horrible template diagnostic messages (you don't use templates!), you'll in fact have better warnings and errors.

C++0x to save the day

Posted Jun 19, 2008 0:37 UTC (Thu) by flewellyn (subscriber, #5047) [Link]

I see the problem: C++ creates a metalanguage to describe types in the language.  But the
metalanguage itself lacks types, so you create a meta-metalanguage to describe types in the
metalanguage.  What happens when you want to have types in concepts?  A
meta-meta-metalanguage?

This is an argument in favor of reflection.

C++0x to save the day

Posted Jun 19, 2008 3:02 UTC (Thu) by pynm0001 (guest, #18379) [Link]

Concepts are not types, and are not a panacea, as what they test for will have to be kept in
sync with what the template class actually requires.  But acting like it's some kind of
infinite recursive type is foolhardy and leads me to believe you haven't looked at concepts
yet. ;)

Or to put it another way, why are people inundated in metametametainfo nowadays, what with the
explosion of features that take advantage of metainfo about our information?

But why are we complaining about this anyways?  unwieldy compiler error messages *are* a
problem, and if were as simple as simply changing the compiler a bit that would have already
been done.  Even scripts that try to condense the error messages down a bit after the fact
don't help.  Concepts allow you to fail-fast when compiling.

error: foo.cpp:15 -- Cannot instantiate template<class T> Foo with T = Widget because Widget
is not Iterable (concept defined in foo.h:17).

is much more useful than an error message talking about missing copy constructors or something
in Widget.  Concepts are optional but you only have to put in a bit of work to add them to
your library and they work on everything which uses that template, it doesn't need changes in
your code to derive from IEnumerable or something crazy, which is good if you can't change
your class hierarchy, or simply don't want to derive from a class just to prove you've
implemented some specific functions.

Careful use of concepts will allow a program to be able to avoid having to use adaptor classes
to interface with a template as well, as instead of having to rename functions you can use a
concept_map to tell the template what function to call in class Foo to get the effect of
push_back, for instance.  So when the template calls T::push_back, the correct Foo::append()
would get called instead.

So yes, you may have to do extra work, but it's optional.  If you don't use concepts then you
get what you have now, if you do use concepts your programs can get better, easier to read and
easier to build.  I think of this like the visibility support added to g++ in 4.0.  It was a
pain to figure out but it has lead to great speedups so I'm not upset that they developed it.
I'm actually quite pleased.

I have to disagree:

Posted Jun 19, 2008 15:09 UTC (Thu) by hummassa (subscriber, #307) [Link]

> But why are we complaining about this anyways?  unwieldy compiler error
> messages *are* a problem, and if were as simple as simply changing the
> compiler a bit that would have already been done.  Even scripts that
> try to condense the error messages down a bit after the fact don't
> help.  Concepts allow you to fail-fast when compiling.

This is wrong in many levels; I don't know where to start... so, I'll 
reply to your example:

> error: foo.cpp:15 -- Cannot instantiate template<class T> Foo with T =
> Widget because Widget is not Iterable (concept defined in foo.h:17).

The correct error message would be IMHO:

error: foo.cpp:15 -- cannot instantiate template<class T> Foo with T = 
Widget because Widget::operator++(int) nor ::operator++(Widget&,int) 
exists. Foo<T> is defined at foo.h:20 and uses said operator at foo.h:25.

This is feasible because when Foo<T> was defined, it already had the 
information that T needed T::operator*() or ::operator*(T&) and 
T::operator++(int) or ::operator++(T&, int), just because foo.h:25 is:

while( *t++ ) { do_something_with(t); }

I understand that "Widget is not Iterable" is even easier than "Widget:: 
operator*() not defined", so I still think that concepts are a good idea 
as documentation facilities, but I can't agree that good error 
messages "were impossible to attain before concepts".

Just for the kicks, I tried to see what would be the error message in 
such a case:

> um.cc: In static member function 'static int Foo<T>::foo(T) [with T =
> std::basic_string<char, std::char_traits<char>, std::allocator<char>
> >]':
> um.cc:16:   instantiated from here
> um.cc:8: error: no 'operator++(int)' declared for postfix '++', trying
> prefix operator instead
> um.cc:8: error: no match for 'operator++' in '++x'

um.cc:8 is the usage of *t++ in Foo<T>::foo(T); actually, the message 
contains almost every single useful bit of information, but in a garbled 
way: it satys that the problem is the usage of a postfix ++ in line 8, 
when instantiated on line 16. But it forgets to say what type it's 
instantiated to... this can't be hard to correct IMHO.

I have to disagree:

Posted Jun 19, 2008 18:08 UTC (Thu) by nix (subscriber, #2304) [Link]

The [with T=...] bit says what the type the template is being instantiated 
with is. (Ow. Nasty center-embedding. Sorry.)

Many days later...

Posted Aug 24, 2008 11:08 UTC (Sun) by hummassa (subscriber, #307) [Link]

I forgot to explain that it doesn't say the "most short, meaningful to the
lines where the error ocurred name", /in/ /casu/ "std::string".

C++0x to save the day

Posted Jun 19, 2008 3:58 UTC (Thu) by elanthis (subscriber, #6227) [Link]

Reflection happens at run time, or requires an even more complex meta-language (.e.g.
meta-c++) in order to handle them at compile time.

Concepts are, for all intents and purposes, just a simple way of specifying type constraints.
Standard C++ allows you to have very specific type matches (unsigned long, Foo*, etc.) or very
generic types (typename anything), while Concepts add the ability to describe a type that
follows some particular contract (anything that can be added together, anything with a
set(string,int) method, anything with a default constructor, etc.).

However, the unwieldly error messages produced by C++ really aren't directly related to the
lack of Concepts in the current language.  It's mostly just the compilers explicitly choosing
to be too verbose.

Say your code looks like this:

typedef vector<int> vint;
vint numbers;
numbers.add("foo");

You're going to get a huge error including things like std::basic_vector<int>::blah::blargh
etc. etc.  What is happening is that the compiler is substituting in the actual type in the
AST/IR instead of the type specified by the user.

A compiler like Clang (eventually) will not have this issue.  Instead of spitting out the base
template type and every child in the chain of derived templates, it can just say "vint
(typedef std::vector<int>) has no method matching ::add(char*)" and then maybe spit out the
other overloaded versions of ::add() a la GCC.

GCC and the other C++ compilers spit out huge error messages for templates because the
compiler authors just didn't care enough (or didn't think enough) to support cleaner error
messages.  Nothing in C++ itself makes those cleaner messages impossible, or even all that
difficult.

C++0x to save the day

Posted Jun 18, 2008 22:47 UTC (Wed) by ncm (subscriber, #165) [Link]

C++ appeals to serious writers of useful libraries, and users of those libraries.  

There's nothing freaky here. The compiler can't know, by itself, that a template argument must
model a numeric type.  Concepts allow the library writer to say so. Then, when a user tries to
use the template on something that isn't numeric, the compiler can say so right there, instead
of complaining that some expression down in the function body is ill-formed.

As noted above, macros in C have the same problem, but hardly anybody tries to do anything
ambitious with C macros; far fewer do it successfully, in part because of precisely this sort
of problem.  In essence, a C++ library can extend the compiler, and compiler extensions need
their own error messages.  Concepts gives library writers a practical way to provide them, to
describe the error in terms of the library interface, not in terms of details of the library
implementation, which is all a compiler could conceivably do by itself.

C++0x to save the day

Posted Aug 7, 2009 19:50 UTC (Fri) by hummassa (subscriber, #307) [Link]

> The compiler can't know, by itself, that a template argument must model a numeric type.

Sure it can. The compiler has access to the source of the template; it will have to generate code based on that source eventually, so it knows what it needs.

Even if the compiler does not "plan ahead", during the instantiation phase it can deduce WHY the instantiation went wrong, instead of spilling WHAT went wrong with it... and point to the right lines of code, and giving meaningful class names instead of "complete" class names (IOW:

std::string
instead of
std::basic_string<char, std::char_traits<char>, std::allocator<char>>

)...

Sometimes C++ is faster

Posted Jun 19, 2008 7:19 UTC (Thu) by eric.rannaud (guest, #44292) [Link]

The debugging problem (function appears on one line) can be dealt with: 
pipe the output of cpp to indent(1) and do a little bit of processing on 
the preprocessors line markers (like: # 1 "/usr/include/stdint.h"). Gdb 
now sees the function on several lines, and it's much easier to use the 
debugger on them.

Sometimes C++ is faster

Posted Jun 18, 2008 19:06 UTC (Wed) by ncm (subscriber, #165) [Link]

The fundamental advantage (inlined templates over macros) is that the compiler knows what's
going on.  First, it can provide type checking, which with good design can prevent many usage
errors.  Second, it can provide type-based dispatching, enabling different algorithms to be
used for different data structures.  The optimal sort for a three-element array is
fundamentally different from that for one of unknown size.  The optimal sort for a linked list
is conceptually similar to that for an array, but an entirely different code sequence.  

Using template type matching, you can present the same interface for all these cases, and
generate appropriate code for each.  Try doing that with C macros, or even Lisp macros.

You might provide macros for all the cases, under different names, but you probably wouldn't,
because you could only use them locally.  Templates may be packaged cleanly and safely enough
to be generally usable, justifying more attention to their creation and distribution.

C++ may be faster in other places.  In a deep call chain, where each caller must check and
dispatch on the return value of each call, using exceptions well instead can make the code
both faster and much more compact and readable.  A taste of the difference may be seen in
numeric codes that rely on checking for Inf and NaN at the end of a computation; imagine
checking for all those conditions after each multiply!

Sometimes C++ is faster

Posted Jun 18, 2008 20:00 UTC (Wed) by flewellyn (subscriber, #5047) [Link]

Try doing that with C macros, or even Lisp macros.

You wouldn't use macros for that in (Common) Lisp, that's not what they're for. You'd use CLOS generic functions, which would dispatch on the argument types. Then you get a nice, natural, functional interface with multiple dispatch as a free bonus.

Sometimes C++ is faster

Posted Jun 18, 2008 21:00 UTC (Wed) by ncm (subscriber, #165) [Link]

Sorry, f., we're talking here about speed, hence compile-time dispatching.  If you don't care
about runtime cost, all kinds (not to say "sorts") of notational convenience are easy to
support.

Sometimes C++ is faster

Posted Jun 18, 2008 21:29 UTC (Wed) by flewellyn (subscriber, #5047) [Link]

In CL, if you want compile-time dispatching, you just declare the types of the method
arguments using DECLARE.  Then the compiler sees that and "hard-wires" the method dispatch.

Sometimes C++ is faster

Posted Jun 18, 2008 21:51 UTC (Wed) by ncm (subscriber, #165) [Link]

Does CL support overloading?  Or would you need to give the functions DECLAREd with different
argument types different names?

Sometimes C++ is faster

Posted Jun 18, 2008 21:58 UTC (Wed) by flewellyn (subscriber, #5047) [Link]

You would DECLARE the types of the arguments in the calling function.  Then (in some
implementations, anyway) the compiler would see that the arguments to the generic function are
of a particular type, and do the dispatch at compile-time.  No changes to the called GF
required.

Sometimes C++ is faster

Posted Jun 18, 2008 21:10 UTC (Wed) by ncm (subscriber, #165) [Link]

I guess I should mention that this sort of compile-time dispatching is natural, without
macros, in ML variants and in Haskell.  Such languages can be good for coding compilers, given
an implementation with a GC that respects cache locality.  Recoding Gcc in Eager Haskell, it
might take years before you got anything useful, but you'd learn a lot, and have a better
sense of what the successor to Haskell should look like.

Sometimes C++ is faster

Posted Jun 18, 2008 21:31 UTC (Wed) by flewellyn (subscriber, #5047) [Link]

Mmh, well, I was hardly recommending that anybody rewrite GCC in Common Lisp.  While I'm sure
someone could do it, the result would be a hell of a lot harder to bootstrap.  :-)

Copyright © 2012, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds