I tried it. It takes ~ 0.004 seconds for a million
vector<char>::push_back calls, if I build with -O3, so only very
slightly slower than the direct assignment into a char array.
That's not surprising since vector<char>::push_back is not a
virtual method and can be inlined, so the machine code should be
the same as a simple array element assignment + size increment. In
fact, if instead of using push_back I simply resize the vector to
have a million elements and then use simple element assignments,
then the vector performance is the same as using a raw array, in
fact a little faster for some reason.
Here's the output, and I've also attached the modified program.
String append with initial capacity 0 took 0.409247 seconds
String append with initial capacity 1000000 took 0.407078 seconds
NSMutableData appendBytes took 0.033926 seconds
Assigning into char array took 0.003776 seconds
vector.push_back took 0.004577 seconds
vector[i]=ch took 0.002886 seconds
On Feb 12, 2008, at 5:01 PM, John Stiles wrote:
If you've got a little geekery left in you, I'd be highly curious
to know the times for doing a million push_back's into a
vector<char>. I wonder how it compares to NSMutableData.
#import <Foundation/Foundation.h>
#include <vector>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [NSAutoreleasePool new];
NSDate *tic, *toc;
NSMutableString *theString;
int niters = 1000000;
int i;
// start the string off at 0 capacity and let appendFormat
expand it
tic = [NSDate date];
theString = [NSMutableString stringWithCapacity:0];
for (i = 0; i < niters; i++)
[theString appendFormat:@"%d", (i % 10)];
toc = [NSDate date];
printf("String append with initial capacity 0 took %f seconds\n",
[toc timeIntervalSinceDate:tic]);
[pool release];
pool = [NSAutoreleasePool new];
// start the string off with enough capacity to hold the whole
string, so no
// reallocations are necessary
tic = [NSDate date];
theString = [NSMutableString stringWithCapacity:niters];
for (i = 0; i < niters; i++)
[theString appendFormat:@"%d", (i % 10)];
toc = [NSDate date];
printf("String append with initial capacity %d took %f seconds
\n",
niters, [toc timeIntervalSinceDate:tic]);
[pool release];
pool = [NSAutoreleasePool new];
// try using a buffer, using appendBytes:length
tic = [NSDate date];
NSMutableData *buffer = [NSMutableData dataWithCapacity:niters];
for (i = 0; i < niters; i++) {
char ch = (i % 10) + '0';
[buffer appendBytes:&ch length:1];
}
toc = [NSDate date];
printf("NSMutableData appendBytes took %f seconds\n",
[toc timeIntervalSinceDate:tic]);
[pool release];
pool = [NSAutoreleasePool new];
// finally, try assigning directly to a memory buffer
tic = [NSDate date];
buffer = [NSMutableData dataWithCapacity:niters];
char *chars = (char*)[buffer mutableBytes];
for (i = 0; i < niters; i++) {
char ch = (i % 10) + '0';
chars[i] = ch;
}
toc = [NSDate date];
printf("Assigning into char array took %f seconds\n",
[toc timeIntervalSinceDate:tic]);
std::vector<char> vecchars;
vecchars.reserve(niters);
tic = [NSDate date];
for (i = 0; i < niters; i++)
vecchars.push_back((i) + '0');
toc = [NSDate date];
printf("vector.push_back took %f seconds\n",
[toc timeIntervalSinceDate:tic]);
vecchars.clear();
vecchars.resize(niters);
tic = [NSDate date];
for (i = 0; i < niters; i++)
vecchars[i] = (i) + '0';
toc = [NSDate date];
printf("vector[i]=ch took %f seconds\n",
[toc timeIntervalSinceDate:tic]);
[pool release];
return 0;
}