Slow performance compared to C++, ideas?

deadalnix deadalnix at gmail.com
Fri Jun 7 08:23:48 PDT 2013


On Friday, 7 June 2013 at 07:31:52 UTC, Walter Bright wrote:
> deadalnix mentioned enforcing 'export' on classes exposed to 
> shared libraries, but then aren't we back to expecting user 
> annotation rather than doing things automatically?

Yes, let me explain more.

The export problem isn't new, and you'll find 2 major approach : 
the UNIX approach of export everything, and the windows approach 
of requiring explicit export.

The first approach tend to show its limit. It limit what the 
optimizer can do, and create binary more and more costly to link 
(especially since the number of symbol tends to explode with 
metaprogramming) (linking a debug version of LLVM as shared 
object for instance is quite costly).

Both GCC and clang propose language extensions to manage export 
explicitly on UNIXes.

Additionally, it is beneficial to be very picky about what is 
exported. Once something is exported, you are tied to an API (as 
with public) but also to an ABI. Adding a function to a class for 
instance, can cause a relayout of the vtable. None of the 
existing interface is broken, but the shared object is broken 
anyway, because of symbols it don't use.

Considering this, we need either a way to export explicitly, or 
the other way around. It is also worth noting that consistency 
accross plateforms is a plus, and this is an area where we can do 
better that C (and we already do).

Regarding virtual in particular, it is known that calling a 
virtual method have a cost. It cause an indirect branch, but also 
prevent the compiler from optimizing, as the call is opaque. The 
same way, calling to a shared object is opaque to the compiler, 
and so, you can't get the full benefice of finalizing the 
exported function.

Requiring classes to be exported provide the following benefit :
  - LTO can finalize methods that aren't overridden. It include 
function that you want virtual by design, but you don't use that 
capability is your specific situation. In this regard, this is 
superior to the explicit virtual solution as it do not require to 
annotate virtual and can finalize method that would have to be 
annotated virtual.
  - Shared object can be stripped of all non exported symbols, 
reducing their size.
  - Reduce the surface area of breakage for shared objects.

It however require careful crafting of exported objects. I think 
this is mitigated by the fact that shared object interface 
require careful crafting anyway, as what is exported cannot be 
unexported (and cannot even change its ABI in way that aren't 
easily visible in the source).

The solution can be completed later by a tool as Andrei proposed 
(great idea), but by itself provide a lot of opportunity to 
finalize automagically. As you argued, this is the best way to go.

Executive summary :
  - We can provide a toll to finalize the whole program.
  - We can automatically finalize everything that isn't exported.
  - We don't break any code.
  - We get consistency between windows and UNIXes.
  - Manu will rant.

I see only benefits :D


More information about the Digitalmars-d mailing list