Code::Blocks Forums

Developer forums (C::B DEVELOPMENT STRICTLY!) => Development => Topic started by: JThedering on August 26, 2006, 03:40:30 pm

Title: Compilation much slower under Linux than under Windows
Post by: JThedering on August 26, 2006, 03:40:30 pm
I noticed it for a long time, but now I'd like to do something about it:
When compiling a project in C::B under Linux, the compilation is much slower(in my example project ~15 s) as when using a makefile to do the same steps (~2.5 s).
This problem doesn't exist on Windows, there C::B is equally fast.

I could make it faster by increasing the process count to the amount of source files in Settings->Compiler&Debugger->Other, but it's still not as fast (~ 4 s) because the linking step has to wait until the compiler steps are finished.

I could reduce the problem to the PipedProcess class by testing the behaviour of this class when executing a program. More precisely I could reduce it to the wxExecute call. When I change the wxExecute call to work synchronously, it's as fast as make, but in asynchronous mode, it takes some time until OnTerminate of the PipedProcess is called. (Some values: Compiling a simple hello world C program using "gcc -c test.c" takes 70 ms when doing it synchronously, but 1.4 s asynchronously)

I also made another test: I manually forked the process and called exec, while returning the process id in the parent process, so that it does the same as wxExecute can do. Then I used waitpid frequently (every 10 ms) to check if the process is finished. If I use my simple "version" of wxExecute, it's ~70 ms, but when I create the process with wxExecute, it's slow.

So I ask: Is there a known workaround to this problem or has anyone else any knowledge that could help? Is this a bug in wxWidgets?
Title: Re: Compilation much slower under Linux than under Windows
Post by: Game_Ender on August 26, 2006, 04:11:07 pm
That is odd because to my knowledge in complex projects, like Code::Blocks itself the CB build system is just as fast as make.  When both the autotools and CB project for Code::Blocks are configured with the same build options they should be within about 10% of each other speed wise.  My guess is for small projects, or small files, the overhead of wxExecute is large enough to have a noticeable effect on the build time.

From you findings it seems like you should investigate the wxExectue source code, perhaps you could supply a patch to speed it up on Linux.
Title: Re: Compilation much slower under Linux than under Windows
Post by: thomas on August 26, 2006, 07:52:20 pm
Is this a bug in wxWidgets?
wxExecute is *one* bug. In particular, it is not thread-safe, inefficient, and it can cause re-entrancy even when you do not use multiple threads (runs wxYield() in a spin loop while waiting for the app to terminate).
Unluckily, we're bound to use it, since there is no reasonable alternative (apart from rewriting it from scratch). Using a worker thread that simply calls popen() would be just perfect, this would be a lot more efficient and safe. However, popen  won't do under Windows :(
Title: Re: Compilation much slower under Linux than under Windows
Post by: takeshimiya on August 26, 2006, 09:29:44 pm
Maybe someone wants to fix the wxExecute implementation?

In the Unix wxExecute implementation I can read:
Code: cpp
#if wxUSE_THREADS
    // fork() doesn't mix well with POSIX threads: on many systems the program
    // deadlocks or crashes for some reason. Probably our code is buggy and
    // doesn't do something which must be done to allow this to work, but I
    // don't know what yet, so for now just warn the user (this is the least we
    // can do) about it
    wxASSERT_MSG( wxThread::IsMain(),
                    _T("wxExecute() can be called only from the main thread") );
#endif // wxUSE_THREADS

And in the Windows wxExecute implementation I can read:
Code: cpp
#if wxUSE_THREADS
    // for many reasons, the code below breaks down if it's called from another
    // thread -- this could be fixed, but as Unix versions don't support this
    // neither I don't want to waste time on this now
    wxASSERT_MSG( wxThread::IsMain(),
                    _T("wxExecute() can be called only from the main thread") );
#endif // wxUSE_THREADS


Aside, popen:
Code: cpp
// this function replaces the standard popen() one: it launches a process
// asynchronously and allows the caller to get the streams connected to its
// std{in|out|err}
//
// on error NULL is returned, in any case the process object will be
// deleted automatically when the process terminates and should *not* be
// deleted by the caller
static wxProcess *Open(const wxString& cmd, int flags = wxEXEC_ASYNC);


JThedering: if you could fix the above wxExecute implementations, I'm sure the wxWidgets team would greatly appreciate it. :)