From: Hicham Mouline on
Hello,

Are there any articles comparing the cases/reasons when/why to use memset vs
fill, vs writing a loop by hand?

Regards,



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Razvan Cojocaru on
> Are there any articles comparing the cases/reasons when/why to use memset vs
> fill, vs writing a loop by hand?

The STL chapters in Bjarne Stroustrup's "The C++ Programming Language"
book will tell you why.

In short:

1. memset() is _very_ low-level, and you should prefer fill() wherever
it makes sense to think of the data being filled as a C++ container. I'm
assuming you want to fill a C-style array with some value, because
obviously you wouldn't be able to memset() a vector<T> or a list<T>.
Fill() makes your code a bit more portable. That is, if you later decide
to use a different container, you can simply change the type and the
rest of the code will continue to work.

2. using the STL algorithms instead of writing loops by hand insures at
least two good things: A. the code looks nicer and it's easier to
understand (because you're naming the function of the loop instead of
having to read the implementation and figure out what it does), and B.
it's _faster_. Some algorithms can take advantage of the exact
containter type they're working on, and have better complexity than your
"manual" loops would have had.


Hope this helps,
--
Razvan Cojocaru
KeyID: 0x04CA34DE


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Lailoken on
On May 31, 8:10 am, "Hicham Mouline" <hic...(a)mouline.org> wrote:
> Hello,
>
> Are there any articles comparing the cases/reasons when/why to use memset vs
> fill, vs writing a loop by hand?

memset is usually the fastest way (make sure to multiply with
sizeof(type))
fill is the most portable way to initialize arrays of any type (and
would work well with templates, etc).

writing it by hand should be avoided... you cannot do it faster than
memset in most cases (anecdotal)

(It is fun however to learn how to use Duff's device, and then later
learn not to use it.)


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: gast128 on
On 31 mei, 17:10, "Hicham Mouline" <hic...(a)mouline.org> wrote:
> Hello,
>
> Are there any articles comparing the cases/reasons when/why to use memset vs
> fill, vs writing a loop by hand?

One reason could be performance. On VStudio2003 memset is on average
50% faster than std::fill. Ofc memset works only with pod and built in
types.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Hakusa on
On May 31, 11:10 am, "Hicham Mouline" <hic...(a)mouline.org> wrote:
> Hello,
>
> Are there any articles comparing the cases/reasons when/why to use memset vs
> fill, vs writing a loop by hand?

If you want an article, there's always google:
http://stackoverflow.com/questions/1373369/what-is-faster-prefered-memset-or-for-loop-to-zero-out-an-array-of-doubles

It was the second link google gave, the first being your post! Note
the comments on the first answer which state that std::fill and
std::copy are sometimes specialized for POD containers. Theoretically,
i suppose it should make a difference between std::fill and memset.
But...

#include <algorithm>
#include <cstring>
using namespace std;

// Note:
// usingbe = using [begin,end)
// usingbs = using [begin,begin+size)

void usingbe_memset( int* begin, int* end, int value )
{
memset( begin, value, (end-begin)*sizeof(int) );
}
void usingbs_memset( int* begin, size_t size, int value )
{
memset( begin, value, size );
}

void usingbe_fill( int* begin, int* end, int value )
{
std::fill( begin, end, value );
}
void usingbs_fill( int* begin, size_t size, int value )
{
std::fill_n( begin, size, value );
}

void usingbe_loop( int* begin, int* end, int value )
{
while( begin != end )
*(begin++) = value;
}
void usingbs_loop( int* begin, size_t size, int value )
{
while( size-- )
*(begin++) = value;
}

Compiled with g++ version 4.4.1, command line options "-c -O3 -S". ("-
c" removes the need for main().) The assembly, for brevity, i've
posted here: http://pastebin.com/PVUUGGqH

For those who can't read assembly, the code for usingb[se]_memset
neither actually calls memset, nor loops, but instead uses one
instruction, "rep stosb", which i highlighted, that does the job.
However, every other function uses pretty much the exact same loop.
MSVC produced similar results.

So, theoretically, there is no difference and your compiler will
optimize everything; in reality, that is not always true. Since this
seems to go against the general advice, i wonder if either my test is
poorly designed or my compilers just don't do this optimization.
Perhaps there's another compiler option i need enabled.

Other than that, std::fill is more generic than memset since it works
with any type. std::fill is more clear than a for loop because when
you write
for(int i=0; i < LEN; i++ )
a[i] = X;
the meaning of the loop is implied, but not as explicit as
std::fill( a, a+LEN, X );


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]