Vector Performance?

I

Immortal Nephi

I want to know if vector performance is faster than traditional char
performance through loop.
I can choose either method 1 or method 2 if both methods have fixed
size and data is in range of array length. I would prefer to use
method 2, but method 1 has short code lines than method 2 does.


Method 1:

const int size = 256;
vector< char > source, target;

for( int index = 0; index < size; index++ )
source.push_back( index );

target = source;


Method 2:
const int size = 256;
char *source = new char[ size ];
char *target = new char[ size ];

for( int index = 0; index < size; index++ )
source[ index ] = index;

for( int index = 0; index < size; index++ )
target[ index ] = source[ index ];

delete [] target;
delete [] source;
 
Ö

Öö Tiib

        I want to know if vector performance is faster than traditional char
performance through loop.
        I can choose either method 1 or method 2 if both methods have fixed
size and data is in range of array length.  I would prefer to use
method 2, but method 1 has short code lines than method 2 does.

Method 1:

        const int size = 256;
        vector< char > source, target;

        for( int index = 0; index < size; index++ )
                source.push_back( index );

        target = source;

Method 2:
        const int size = 256;
        char *source = new char[ size ];
        char *target = new char[ size ];

        for( int index = 0; index < size; index++ )
                source[ index ] = index;

        for( int index = 0; index < size; index++ )
                target[ index ] = source[ index ];

        delete [] target;
        delete [] source;

If both arrys have fixed same size i would consider method 3.

#include<algorithm>
void method3()
{
const int size = 256;
char source[ size ];
char target[ size ];
for( int i = 0; i < size; i++ )
{
source[ i ] = char( i );
}
std::copy( source, source+size, target );
}
 
M

Marcel Müller

Immortal Nephi wrote:

The performance of method 2 will always be better, since vector is a
dynamically sized container that has to check for sufficient space every
time. In your example it will additionally do reallocations, because you
missed to tell him the size.
Method 1:

const int size = 256;
vector< char > source(size), target(size);

If you dislike the code length of method 2 you should look for an array
class like boost::scoped_array.

And, of course, if size is a compile time constant and the stack size is
no concern you may avoid the allocations at all with local arrays:
char source[size], target [size];


Marcel
 
Ö

Öö Tiib

Öö Tiib said:
If both arrys have fixed same size i would consider method 3.
#include<algorithm>
void method3()
{
const int size = 256;
char source[ size ];
char target[ size ];
for( int i = 0; i < size; i++ )
{
source[ i ] = char( i );
}
std::copy( source, source+size, target );
}

haven't looked inside std::copy, but it may be worth adding

target.reserve(size);

just before the last line. Forces it to allocate all the target memory
in one go.

What? Did you try it? It will not compile with such a line added into
it.
 
J

Jonathan Lee

        target.reserve(size);
        target = source;

I'd be really surprised if vector<> didn't call reserve()
during assignment from another vector...

--Jonathan
 
T

tni

Immortal Nephi said:
Method 1:

const int size = 256;
vector< char> source, target;

for( int index = 0; index< size; index++ )
source.push_back( index );

target = source;


Method 2:
const int size = 256;
char *source = new char[ size ];
char *target = new char[ size ];

for( int index = 0; index< size; index++ )
source[ index ] = index;

for( int index = 0; index< size; index++ )
target[ index ] = source[ index ];

delete [] target;
delete [] source;

const int size = 256;
vector<char> source;
source.reserve(size);
for (int i = 0; i< size; ++i)
source.push_back(i);
vector<char> target = source;

When compared to method 2, the above is just as fast, manages memory
just as well, requires fewer lines of code, and handles exceptions
better.

Bad advice, REALLY bad advice. Neither GCC nor Visual Studio can
properly optimize Method 1. There is going to be a call to push_back in
each iteration (not inlined, there is quite a bit of stuff in there).
This is a good way to decrease performance by a factor of 10 or more.
Quit worrying about such micro-optimizations. Note that the only
significant difference between the code I presented and your Method 1 is
the addition of the "reserve" command.

Quite wrong.

Method 1 disassembly (not showing push_back, it's quite big):

for( int index = 0; index < size; index++ )
00AF108F xor ebx,ebx
source.push_back( index );
00AF1091 lea eax,[esp+13h]
00AF1095 lea ecx,[esp+14h]
00AF1099 mov byte ptr [esp+13h],bl
00AF109D call std::vector<char,std::allocator<char> >::push_back
(0AF1220h)
00AF10A2 inc ebx
00AF10A3 cmp ebx,100h
00AF10A9 jl wmain+51h (0AF1091h)


Method 2 disassembly:

for( int index = 0; index < size; index++ )
00E8101C xor ecx,ecx
00E8101E mov edi,edi
source[ index ] = index;
00E81020 mov byte ptr [ecx+esi],cl
00E81023 inc ecx
00E81024 cmp ecx,100h
00E8102A jl wmain+20h (0E81020h)
 
D

Daniel Pitts

Immortal Nephi said:
Method 1:

const int size = 256;
vector< char> source, target;

for( int index = 0; index< size; index++ )
source.push_back( index );

target = source;


Method 2:
const int size = 256;
char *source = new char[ size ];
char *target = new char[ size ];

for( int index = 0; index< size; index++ )
source[ index ] = index;

for( int index = 0; index< size; index++ )
target[ index ] = source[ index ];

delete [] target;
delete [] source;

const int size = 256;
vector<char> source;
source.reserve(size);
for (int i = 0; i< size; ++i)
source.push_back(i);
vector<char> target = source;

When compared to method 2, the above is just as fast, manages memory
just as well, requires fewer lines of code, and handles exceptions
better.

Bad advice, REALLY bad advice. Neither GCC nor Visual Studio can
properly optimize Method 1. There is going to be a call to push_back in
each iteration (not inlined, there is quite a bit of stuff in there).
This is a good way to decrease performance by a factor of 10 or more.
Quit worrying about such micro-optimizations. Note that the only
significant difference between the code I presented and your Method 1 is
the addition of the "reserve" command.

Quite wrong.

Method 1 disassembly (not showing push_back, it's quite big):

for( int index = 0; index < size; index++ )
00AF108F xor ebx,ebx
source.push_back( index );
00AF1091 lea eax,[esp+13h]
00AF1095 lea ecx,[esp+14h]
00AF1099 mov byte ptr [esp+13h],bl
00AF109D call std::vector<char,std::allocator<char> >::push_back (0AF1220h)
00AF10A2 inc ebx
00AF10A3 cmp ebx,100h
00AF10A9 jl wmain+51h (0AF1091h)


Method 2 disassembly:

for( int index = 0; index < size; index++ )
00E8101C xor ecx,ecx
00E8101E mov edi,edi
source[ index ] = index;
00E81020 mov byte ptr [ecx+esi],cl
00E81023 inc ecx
00E81024 cmp ecx,100h
00E8102A jl wmain+20h (0E81020h)
Show the compiler version and command line, or it didn't happen.
 
T

tni

Show the compiler version and command line, or it didn't happen.

VS 2010, options:

/Zi /nologo /W3 /WX- /O2 /Oi /Oy- /GL /D "WIN32" /D "NDEBUG" /D
"_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm- /EHsc /GS /Gy /fp:precise
/Zc:wchar_t /Zc:forScope /Fa"Release\" /Fo"Release\"
/Fd"Release\vc100.pdb" /Gd /analyze- /errorReport:queue

(GCC at O2 / O3 doesn't do better.)
 

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,774
Messages
2,569,596
Members
45,143
Latest member
SterlingLa
Top