This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/14563] new/delete much slower than malloc/free because of sjlj exceptions
- From: "kjd at duda dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 10 Nov 2004 17:05:32 -0000
- Subject: [Bug target/14563] new/delete much slower than malloc/free because of sjlj exceptions
- References: <20040312233606.14563.paulthomas2@wanadoo.fr>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Additional Comments From kjd at duda dot org 2004-11-10 17:05 -------
(In reply to comment #40)
> Ron, can you please attach your testcase that shows the problem to this PR?
> This PR is a regression on cygwin because the speed is back with 3.2.
Here's a test case for you...
-Ken
-------------------------------------------------------
// Uncomment one of these defines.
// With the first define uncommented, I get 3.293 usec per "operator new" use.
// With the second define uncommented, I get 1.019 usec per "operator new" use.
// A high price to pay for having one's exceptions properly declared!
//#define THROW throw (std::bad_alloc)
#define THROW
// These definitions are taken straight from libstdc++.
#include "new"
#include <exception_defines.h>
using std::new_handler;
using std::bad_alloc;
extern "C" void *malloc (std::size_t);
extern new_handler __new_handler;
void *
operator new (std::size_t sz) THROW
{
void *p;
/* malloc (0) is unpredictable; avoid it. */
if (sz == 0)
sz = 1;
p = (void *) malloc (sz);
while (p == 0)
{
new_handler handler = __new_handler;
if (! handler)
#ifdef __EXCEPTIONS
throw bad_alloc();
#else
std::abort();
#endif
handler ();
p = (void *) malloc (sz);
}
return p;
}
void *
operator new[] (std::size_t sz) THROW
{
return ::operator new(sz);
}
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
typedef unsigned long long u64;
typedef u64 Usec;
#ifdef WIN32
#include <Windows.h>
inline Usec Now()
{
DWORD ticks = GetTickCount();
return ((Usec) ticks) * 1000;
}
#else
#include <sys/types.h>
#include <sys/time.h>
inline Usec Now()
{
struct timeval tv;
if( gettimeofday( &tv, 0 ) ) {
perror( "gettimeofday" );
exit( 1 );
}
return ((Usec) tv.tv_sec) * 1000000 + tv.tv_usec;
}
#endif
using namespace std;
main()
{
int sizeMin = 4;
int sizeMax = 100;
int allocsOutstanding = 1000;
int reps = 1000;
int allocsPerRep = 1000;
int sizeRange = sizeMax - sizeMin;
char ** ptrs = (char **) malloc( sizeof( char * ) * allocsOutstanding );
memset( ptrs, 0, sizeof( char * ) * allocsOutstanding );
Usec start = Now();
int m = reps;
while( m-- ) {
int n = allocsPerRep;
while( n-- ) {
int r = rand();
int index = r % allocsOutstanding;
char * p = ptrs[index];
delete[] p;
// free( p );
int size = (r % sizeRange) + sizeMin;
p = new char[ size ];
// p = (char *) malloc( size );
ptrs[index] = p;
}
}
Usec stop = Now();
double t = ((double) stop - start) / ((double) allocsPerRep * reps);
printf( "cost of new + delete is about %0.3f usec\n", t );
fflush( stdout );
}
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14563