Does object pooling *ever* make sense?

P

pascal.lecointe

Here's more evidence. The code was rewritten to use System.nanoTime()
and to double the amount of memory allocated on each cycle. Times are
still in millisec:

bufsize 1 elapsed = 61
bufsize 2 elapsed = 23
bufsize 4 elapsed = 22
bufsize 8 elapsed = 23
bufsize 16 elapsed = 24
bufsize 32 elapsed = 29
bufsize 64 elapsed = 41
bufsize 128 elapsed = 60
bufsize 256 elapsed = 107
bufsize 512 elapsed = 192
bufsize 1024 elapsed = 344
bufsize 2048 elapsed = 669
bufsize 4096 elapsed = 1308
bufsize 8192 elapsed = 2519
bufsize 16384 elapsed = 4970
bufsize 32768 elapsed = 9934
bufsize 65536 elapsed = 19732
bufsize 131072 elapsed = 39455
bufsize 262144 elapsed = 73419

For very small objects, allocation time is constant. As you get to
larger objects, allocation time doubles as you double the size. Above
~1K, allocation time is close to linear.

Same pattern applies for JDK 1.4, 1.5, and 1.6.

It's probably the time needed to zero the array ... which is
proportional to the size of the array
 
M

Mark Rafn

Chris said:
....
Thanks, everybody, for the insights, but nobody really shed any light on
the original question, which was: what's the breakeven point?

That's because there's no single breakeven point. It depends on usage
patterns, VM implementation, underlying hardware/OS, and probably other
factors.
So I wrote a little code to test the question, pasted below. The code
simply allocates byte [] objects of varying sizes.

To be fair, it should compare that to finding and zeroing byte[] of the same
sizes.
Given that fetching an object from a pool 100,000 times should generally
not take more than a few milliseconds (locking & sync included),

No, but clearing it 100,000 times might take longer than allocating it 100,000
times, on some implementations. And writing into the Nth byte could take
different amounts of time depending on how it's been used before.
looks like object pooling is a necessity when speed is important and
objects get larger than a few dozen Kb in size.

That's far too simplistic a statement. It may be true where your usage
pattern is that you allocate a huge buffer, don't care what's initially in it,
only write to the first byte, never read from it, don't ever need different
ones at the same time, and are running on a specific platform.

That said, I'd agree that it's worth considering pooling for large objects
with a high amount of reuse, especially if they're immutable.
 
B

buggy

Andy said:
Most of my pooled objects are some sort of reference to an external
resource (e.g. a DB connection) that's inherently expensive. I don't
care what the cost of the object itself is, they're pooled to
economise on this external cost and that's not changed by any JVM
improvement.

Yes, but DB connection pooling is entirely different. There is a cost
associated with establishing a DB connection (logging in, creating a
pipe etc). A DB connection pool is vastly preferable (I use proxool).

Mind you ONLY the connection is pooled. All the other objects associated
with the DB call are created normally.
 
C

Chris

That's far too simplistic a statement. It may be true where your usage
pattern is that you allocate a huge buffer, don't care what's initially in it,
only write to the first byte, never read from it, don't ever need different
ones at the same time, and are running on a specific platform.

Here's new benchmark:

I created an array of 1000 128K buffers. This is enough to ensure that
most of them are in main memory, not the processor cache.

I ran Arrays.fill(buffer, (byte)0) on the list 100 times, for a total of
100,000 calls.

The elapsed time? 40 seconds, almost exactly the amount of time required
to allocate 100,000 128K buffers in the previous benchmark. This
indicates that zeroing the arrays probably does take up most of the
time when allocating new objects.

This does support my claim that object pooling is a necessity when using
large objects, *except* in cases where zeroing is necessary.

Which raises a question: wouldn't it be a good idea to have a way to
tell Java, in special cases, not to zero out allocated objects?
 
P

pascal.lecointe

Here's new benchmark:

I created an array of 1000 128K buffers. This is enough to ensure that
most of them are in main memory, not the processor cache.

I ran Arrays.fill(buffer, (byte)0) on the list 100 times, for a total of
100,000 calls.

The elapsed time? 40 seconds, almost exactly the amount of time required
to allocate 100,000 128K buffers in the previous benchmark. This
indicates that zeroing the arrays probably does take up most of the
time when allocating new objects.

This does support my claim that object pooling is a necessity when using
large objects, *except* in cases where zeroing is necessary.

Which raises a question: wouldn't it be a good idea to have a way to
tell Java, in special cases, not to zero out allocated objects?

And it make the case of pooling only useful for primitive array. For
reference arrays, you *must* zero the array when you pull it back in
the pool, otherwise the GC cannot collect the objects referenced by
the array (and bingo the memory leak :)).

And between different primitives, perhaps the time to zero is not the
same (problems of alignment to 32bits or 64bits), perhaps the time to
zero the same array of integer is less than with a byte array

So, it's useful to pool :
- when it's an array of primitives
- and when you don't have to zero the array when you take it from the
pool

And there is the problem of synchronization of the pool... to compare
you must execute the two options

I'll be back with a complete test :)
 
P

pascal.lecointe

And it make the case of pooling only useful for primitive array. For
reference arrays, you *must* zero the array when you pull it back in
the pool, otherwise the GC cannot collect the objects referenced by
the array (and bingo the memory leak :)).

And between different primitives, perhaps the time to zero is not the
same (problems of alignment to 32bits or 64bits), perhaps the time to
zero the same array of integer is less than with a byte array

So, it's useful to pool :
- when it's an array of primitives
- and when you don't have to zero the array when you take it from the
pool

And there is the problem of synchronization of the pool... to compare
you must execute the two options

I'll be back with a complete test :)

<scce>
/**
* Test of the utility of pool for primitive arrays
*/
public class TestPool {

public static final int ITERATIONS = 100000;
public static final int NB_INCREMENTS = 19;

public static void main(String[] args) {
testByteWithPool();
testByteWithoutPool();
testIntWithPool();
testIntWithoutPool();
}

/** An object to lock the pool when we use it */
private static Object poolLock = new Object();
private static boolean poolUsed = false;

private static byte[] bytePool;
private static int[] intPool;
private static Object[] refPool;


private static void testByteWithPool() {
int currentSize = 1;

for (int j = 0; j < NB_INCREMENTS; j++) {

long t1 = System.nanoTime();
// Creation of the pool
synchronized (poolLock) {
bytePool = new byte[currentSize];
poolUsed = false;
}
for (int i = 0; i < ITERATIONS; i++) {
byte[] array = null;
// Get the array from pool
synchronized (poolLock) {
if (poolUsed) {
throw new RuntimeException("pool already in use");
}
array = bytePool;
poolUsed = true;
}
// use the array
array[0] = 1;
// put back the array in the pool
synchronized (poolLock) {
poolUsed = false;
}
}
long t2 = System.nanoTime();
System.out.printf("BYTE POOL : bufsize %d elapsed = %d\n",
currentSize, (t2-t1)/1000000);

currentSize *= 2;
}
}

private static void testByteWithoutPool() {
int currentSize = 1;

for (int j = 0; j < NB_INCREMENTS; j++) {

long t1 = System.nanoTime();
for (int i = 0; i < ITERATIONS; i++) {
// Get the array
byte[] array = new byte[currentSize];
// use the array
array[0] = 1;
}
long t2 = System.nanoTime();
System.out.printf("BYTE NOPOOL : bufsize %d elapsed = %d\n",
currentSize, (t2-t1)/1000000);

currentSize *= 2;
}
}

private static void testIntWithPool() {
int currentSize = 1;

for (int j = 0; j < NB_INCREMENTS; j++) {

long t1 = System.nanoTime();
// Creation of the pool
synchronized (poolLock) {
intPool = new int[currentSize];
poolUsed = false;
}
for (int i = 0; i < ITERATIONS; i++) {
int[] array = null;
// Get the array from pool
synchronized (poolLock) {
if (poolUsed) {
throw new RuntimeException("pool already in use");
}
array = intPool;
poolUsed = true;
}
// use the array
array[0] = 1;
// put back the array in the pool
synchronized (poolLock) {
poolUsed = false;
}
}
long t2 = System.nanoTime();
System.out.printf("INT POOL : bufsize %d elapsed = %d\n",
currentSize, (t2-t1)/1000000);

currentSize *= 2;
}
}

private static void testIntWithoutPool() {
int currentSize = 1;

for (int j = 0; j < NB_INCREMENTS; j++) {

long t1 = System.nanoTime();
for (int i = 0; i < ITERATIONS; i++) {
// Get the array
int[] array = new int[currentSize];
// use the array
array[0] = 1;
}
long t2 = System.nanoTime();
System.out.printf("INT NOPOOL : bufsize %d elapsed = %d\n",
currentSize, (t2-t1)/1000000);

currentSize *= 2;
}
}

}
</scce>

And the results are :

BYTE POOL : bufsize 1 elapsed = 8
BYTE POOL : bufsize 2 elapsed = 4
BYTE POOL : bufsize 4 elapsed = 4
BYTE POOL : bufsize 8 elapsed = 4
BYTE POOL : bufsize 16 elapsed = 3
BYTE POOL : bufsize 32 elapsed = 4
BYTE POOL : bufsize 64 elapsed = 4
BYTE POOL : bufsize 128 elapsed = 4
BYTE POOL : bufsize 256 elapsed = 1
BYTE POOL : bufsize 512 elapsed = 6
BYTE POOL : bufsize 1024 elapsed = 4
BYTE POOL : bufsize 2048 elapsed = 3
BYTE POOL : bufsize 4096 elapsed = 2
BYTE POOL : bufsize 8192 elapsed = 4
BYTE POOL : bufsize 16384 elapsed = 6
BYTE POOL : bufsize 32768 elapsed = 2
BYTE POOL : bufsize 65536 elapsed = 6
BYTE POOL : bufsize 131072 elapsed = 4
BYTE POOL : bufsize 262144 elapsed = 4
BYTE NOPOOL : bufsize 1 elapsed = 3
BYTE NOPOOL : bufsize 2 elapsed = 1
BYTE NOPOOL : bufsize 4 elapsed = 1
BYTE NOPOOL : bufsize 8 elapsed = 4
BYTE NOPOOL : bufsize 16 elapsed = 3
BYTE NOPOOL : bufsize 32 elapsed = 4
BYTE NOPOOL : bufsize 64 elapsed = 8
BYTE NOPOOL : bufsize 128 elapsed = 19
BYTE NOPOOL : bufsize 256 elapsed = 19
BYTE NOPOOL : bufsize 512 elapsed = 49
BYTE NOPOOL : bufsize 1024 elapsed = 80
BYTE NOPOOL : bufsize 2048 elapsed = 162
BYTE NOPOOL : bufsize 4096 elapsed = 308
BYTE NOPOOL : bufsize 8192 elapsed = 651
BYTE NOPOOL : bufsize 16384 elapsed = 1210
BYTE NOPOOL : bufsize 32768 elapsed = 2389
BYTE NOPOOL : bufsize 65536 elapsed = 4750
BYTE NOPOOL : bufsize 131072 elapsed = 9634
BYTE NOPOOL : bufsize 262144 elapsed = 19496
INT POOL : bufsize 1 elapsed = 6
INT POOL : bufsize 2 elapsed = 4
INT POOL : bufsize 4 elapsed = 4
INT POOL : bufsize 8 elapsed = 4
INT POOL : bufsize 16 elapsed = 6
INT POOL : bufsize 32 elapsed = 4
INT POOL : bufsize 64 elapsed = 4
INT POOL : bufsize 128 elapsed = 2
INT POOL : bufsize 256 elapsed = 4
INT POOL : bufsize 512 elapsed = 4
INT POOL : bufsize 1024 elapsed = 4
INT POOL : bufsize 2048 elapsed = 4
INT POOL : bufsize 4096 elapsed = 4
INT POOL : bufsize 8192 elapsed = 7
INT POOL : bufsize 16384 elapsed = 4
INT POOL : bufsize 32768 elapsed = 4
INT POOL : bufsize 65536 elapsed = 2
INT POOL : bufsize 131072 elapsed = 4
INT POOL : bufsize 262144 elapsed = 4
INT NOPOOL : bufsize 1 elapsed = 5
INT NOPOOL : bufsize 2 elapsed = 5
INT NOPOOL : bufsize 4 elapsed = 0
INT NOPOOL : bufsize 8 elapsed = 4
INT NOPOOL : bufsize 16 elapsed = 5
INT NOPOOL : bufsize 32 elapsed = 11
INT NOPOOL : bufsize 64 elapsed = 25
INT NOPOOL : bufsize 128 elapsed = 42
INT NOPOOL : bufsize 256 elapsed = 80
INT NOPOOL : bufsize 512 elapsed = 161
INT NOPOOL : bufsize 1024 elapsed = 306
INT NOPOOL : bufsize 2048 elapsed = 604
INT NOPOOL : bufsize 4096 elapsed = 1180
INT NOPOOL : bufsize 8192 elapsed = 2394
INT NOPOOL : bufsize 16384 elapsed = 4763
INT NOPOOL : bufsize 32768 elapsed = 9541
INT NOPOOL : bufsize 65536 elapsed = 18997
INT NOPOOL : bufsize 131072 elapsed = 38034
INT NOPOOL : bufsize 262144 elapsed = 76232

So we can conclude :
- using the pool for a primitive array is constant (but my pool is
very light, one object, the overhead of a real pool will be much
important)
- zeroing the array of int is four times zeroing the array of byte
- the time is very short, for an array of 256k, creating and
initializing an array if about 0.19 ms

so it really depends if the creation of array is really very intense
in your program

as always, profile first, optimize after :)
 
P

pascal.lecointe

And it make the case of pooling only useful for primitive array. For
reference arrays, you *must* zero the array when you pull it back in
the pool, otherwise the GC cannot collect the objects referenced by
the array (and bingo the memory leak :)).
And between different primitives, perhaps the time to zero is not the
same (problems of alignment to 32bits or 64bits), perhaps the time to
zero the same array of integer is less than with a byte array
So, it's useful to pool :
- when it's an array of primitives
- and when you don't have to zero the array when you take it from the
pool
And there is the problem of synchronization of the pool... to compare
you must execute the two options
I'll be back with a complete test :)

<scce>
/**
* Test of the utility of pool for primitive arrays
*/
public class TestPool {

public static final int ITERATIONS = 100000;
public static final int NB_INCREMENTS = 19;

public static void main(String[] args) {
testByteWithPool();
testByteWithoutPool();
testIntWithPool();
testIntWithoutPool();
}

/** An object to lock the pool when we use it */
private static Object poolLock = new Object();
private static boolean poolUsed = false;

private static byte[] bytePool;
private static int[] intPool;
private static Object[] refPool;

private static void testByteWithPool() {
int currentSize = 1;

for (int j = 0; j < NB_INCREMENTS; j++) {

long t1 = System.nanoTime();
// Creation of the pool
synchronized (poolLock) {
bytePool = new byte[currentSize];
poolUsed = false;
}
for (int i = 0; i < ITERATIONS; i++) {
byte[] array = null;
// Get the array from pool
synchronized (poolLock) {
if (poolUsed) {
throw new RuntimeException("pool already in use");
}
array = bytePool;
poolUsed = true;
}
// use the array
array[0] = 1;
// put back the array in the pool
synchronized (poolLock) {
poolUsed = false;
}
}
long t2 = System.nanoTime();
System.out.printf("BYTE POOL : bufsize %d elapsed = %d\n",
currentSize, (t2-t1)/1000000);

currentSize *= 2;
}
}

private static void testByteWithoutPool() {
int currentSize = 1;

for (int j = 0; j < NB_INCREMENTS; j++) {

long t1 = System.nanoTime();
for (int i = 0; i < ITERATIONS; i++) {
// Get the array
byte[] array = new byte[currentSize];
// use the array
array[0] = 1;
}
long t2 = System.nanoTime();
System.out.printf("BYTE NOPOOL : bufsize %d elapsed = %d\n",
currentSize, (t2-t1)/1000000);

currentSize *= 2;
}
}

private static void testIntWithPool() {
int currentSize = 1;

for (int j = 0; j < NB_INCREMENTS; j++) {

long t1 = System.nanoTime();
// Creation of the pool
synchronized (poolLock) {
intPool = new int[currentSize];
poolUsed = false;
}
for (int i = 0; i < ITERATIONS; i++) {
int[] array = null;
// Get the array from pool
synchronized (poolLock) {
if (poolUsed) {
throw new RuntimeException("pool already in use");
}
array = intPool;
poolUsed = true;
}
// use the array
array[0] = 1;
// put back the array in the pool
synchronized (poolLock) {
poolUsed = false;
}
}
long t2 = System.nanoTime();
System.out.printf("INT POOL : bufsize %d elapsed = %d\n",
currentSize, (t2-t1)/1000000);

currentSize *= 2;
}
}

private static void testIntWithoutPool() {
int currentSize = 1;

for (int j = 0; j < NB_INCREMENTS; j++) {

long t1 = System.nanoTime();
for (int i = 0; i < ITERATIONS; i++) {
// Get the array
int[] array = new int[currentSize];
// use the array
array[0] = 1;
}
long t2 = System.nanoTime();
System.out.printf("INT NOPOOL : bufsize %d elapsed = %d\n",
currentSize, (t2-t1)/1000000);

currentSize *= 2;
}
}

}

</scce>

And the results are :

BYTE POOL : bufsize 1 elapsed = 8
BYTE POOL : bufsize 2 elapsed = 4
BYTE POOL : bufsize 4 elapsed = 4
BYTE POOL : bufsize 8 elapsed = 4
BYTE POOL : bufsize 16 elapsed = 3
BYTE POOL : bufsize 32 elapsed = 4
BYTE POOL : bufsize 64 elapsed = 4
BYTE POOL : bufsize 128 elapsed = 4
BYTE POOL : bufsize 256 elapsed = 1
BYTE POOL : bufsize 512 elapsed = 6
BYTE POOL : bufsize 1024 elapsed = 4
BYTE POOL : bufsize 2048 elapsed = 3
BYTE POOL : bufsize 4096 elapsed = 2
BYTE POOL : bufsize 8192 elapsed = 4
BYTE POOL : bufsize 16384 elapsed = 6
BYTE POOL : bufsize 32768 elapsed = 2
BYTE POOL : bufsize 65536 elapsed = 6
BYTE POOL : bufsize 131072 elapsed = 4
BYTE POOL : bufsize 262144 elapsed = 4
BYTE NOPOOL : bufsize 1 elapsed = 3
BYTE NOPOOL : bufsize 2 elapsed = 1
BYTE NOPOOL : bufsize 4 elapsed = 1
BYTE NOPOOL : bufsize 8 elapsed = 4
BYTE NOPOOL : bufsize 16 elapsed = 3
BYTE NOPOOL : bufsize 32 elapsed = 4
BYTE NOPOOL : bufsize 64 elapsed = 8
BYTE NOPOOL : bufsize 128 elapsed = 19
BYTE NOPOOL : bufsize 256 elapsed = 19
BYTE NOPOOL : bufsize 512 elapsed = 49
BYTE NOPOOL : bufsize 1024 elapsed = 80
BYTE NOPOOL : bufsize 2048 elapsed = 162
BYTE NOPOOL : bufsize 4096 elapsed = 308
BYTE NOPOOL : bufsize 8192 elapsed = 651
BYTE NOPOOL : bufsize 16384 elapsed = 1210
BYTE NOPOOL : bufsize 32768 elapsed = 2389
BYTE NOPOOL : bufsize 65536 elapsed = 4750
BYTE NOPOOL : bufsize 131072 elapsed = 9634
BYTE NOPOOL : bufsize 262144 elapsed = 19496
INT POOL : bufsize 1 elapsed = 6
INT POOL : bufsize 2 elapsed = 4
INT POOL : bufsize 4 elapsed = 4
INT POOL : bufsize 8 elapsed = 4
INT POOL : bufsize 16 elapsed = 6
INT POOL : bufsize 32 elapsed = 4
INT POOL : bufsize 64 elapsed = 4
INT POOL : bufsize 128 elapsed = 2
INT POOL : bufsize 256 elapsed = 4
INT POOL : bufsize 512 elapsed = 4
INT POOL : bufsize 1024 elapsed = 4
INT POOL : bufsize 2048 elapsed = 4
INT POOL : bufsize 4096 elapsed = 4
INT POOL : bufsize 8192 elapsed = 7
INT POOL : bufsize 16384 elapsed = 4
INT POOL : bufsize 32768 elapsed = 4
INT POOL : bufsize 65536 elapsed = 2
INT POOL : bufsize 131072 elapsed = 4
INT POOL : bufsize 262144 elapsed = 4
INT NOPOOL : bufsize 1 elapsed = 5
INT NOPOOL : bufsize 2 elapsed = 5
INT NOPOOL : bufsize 4 elapsed = 0
INT NOPOOL : bufsize 8 elapsed = 4
INT NOPOOL : bufsize 16 elapsed = 5
INT NOPOOL : bufsize 32 elapsed = 11
INT NOPOOL : bufsize 64 elapsed = 25
INT NOPOOL : bufsize 128 elapsed = 42
INT NOPOOL : bufsize 256 elapsed = 80
INT NOPOOL : bufsize 512 elapsed = 161
INT NOPOOL : bufsize 1024 elapsed = 306
INT NOPOOL : bufsize 2048 elapsed = 604
INT NOPOOL : bufsize 4096 elapsed = 1180
INT NOPOOL : bufsize 8192 elapsed = 2394
INT NOPOOL : bufsize 16384 elapsed = 4763
INT NOPOOL : bufsize 32768 elapsed = 9541
INT NOPOOL : bufsize 65536 elapsed = 18997
INT NOPOOL : bufsize 131072 elapsed = 38034
INT NOPOOL : bufsize 262144 elapsed = 76232

So we can conclude :
- using the pool for a primitive array is constant (but my pool is
very light, one object, the overhead of a real pool will be much
important)
- zeroing the array of int is four times zeroing the array of byte
- the time is very short, for an array of 256k, creating and
initializing an array if about 0.19 ms

so it really depends if the creation of array is really very intense
in your program

as always, profile first, optimize after :)

I did the same test with zeroing the array when i take it from the
pool.

The results are :
BYTE POOL : bufsize 1 elapsed = 10
BYTE POOL : bufsize 2 elapsed = 9
BYTE POOL : bufsize 4 elapsed = 7
BYTE POOL : bufsize 8 elapsed = 8
BYTE POOL : bufsize 16 elapsed = 11
BYTE POOL : bufsize 32 elapsed = 13
BYTE POOL : bufsize 64 elapsed = 32
BYTE POOL : bufsize 128 elapsed = 45
BYTE POOL : bufsize 256 elapsed = 83
BYTE POOL : bufsize 512 elapsed = 158
BYTE POOL : bufsize 1024 elapsed = 314
BYTE POOL : bufsize 2048 elapsed = 620
BYTE POOL : bufsize 4096 elapsed = 1230
BYTE POOL : bufsize 8192 elapsed = 2470
BYTE POOL : bufsize 16384 elapsed = 4924
BYTE NOPOOL : bufsize 1 elapsed = 7
BYTE NOPOOL : bufsize 2 elapsed = 2
BYTE NOPOOL : bufsize 4 elapsed = 0
BYTE NOPOOL : bufsize 8 elapsed = 2
BYTE NOPOOL : bufsize 16 elapsed = 4
BYTE NOPOOL : bufsize 32 elapsed = 4
BYTE NOPOOL : bufsize 64 elapsed = 7
BYTE NOPOOL : bufsize 128 elapsed = 20
BYTE NOPOOL : bufsize 256 elapsed = 25
BYTE NOPOOL : bufsize 512 elapsed = 39
BYTE NOPOOL : bufsize 1024 elapsed = 82
BYTE NOPOOL : bufsize 2048 elapsed = 161
BYTE NOPOOL : bufsize 4096 elapsed = 308
BYTE NOPOOL : bufsize 8192 elapsed = 602
BYTE NOPOOL : bufsize 16384 elapsed = 1192
INT POOL : bufsize 1 elapsed = 9
INT POOL : bufsize 2 elapsed = 6
INT POOL : bufsize 4 elapsed = 6
INT POOL : bufsize 8 elapsed = 10
INT POOL : bufsize 16 elapsed = 13
INT POOL : bufsize 32 elapsed = 13
INT POOL : bufsize 64 elapsed = 21
INT POOL : bufsize 128 elapsed = 45
INT POOL : bufsize 256 elapsed = 84
INT POOL : bufsize 512 elapsed = 161
INT POOL : bufsize 1024 elapsed = 320
INT POOL : bufsize 2048 elapsed = 618
INT POOL : bufsize 4096 elapsed = 1252
INT POOL : bufsize 8192 elapsed = 2478
INT POOL : bufsize 16384 elapsed = 4953
INT NOPOOL : bufsize 1 elapsed = 5
INT NOPOOL : bufsize 2 elapsed = 1
INT NOPOOL : bufsize 4 elapsed = 2
INT NOPOOL : bufsize 8 elapsed = 6
INT NOPOOL : bufsize 16 elapsed = 6
INT NOPOOL : bufsize 32 elapsed = 7
INT NOPOOL : bufsize 64 elapsed = 24
INT NOPOOL : bufsize 128 elapsed = 39
INT NOPOOL : bufsize 256 elapsed = 82
INT NOPOOL : bufsize 512 elapsed = 152
INT NOPOOL : bufsize 1024 elapsed = 302
INT NOPOOL : bufsize 2048 elapsed = 617
INT NOPOOL : bufsize 4096 elapsed = 1201
INT NOPOOL : bufsize 8192 elapsed = 2399
INT NOPOOL : bufsize 16384 elapsed = 4790

The "manual" zeroing of the array of byte is four times the self
zeroing of the array (by the operator new)
 

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,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top