-
February 2nd, 2009, 11:06 AM
#1
memcpy() analog
Hi, all.
Ask to share your opinions.
What is the best way for FAST coping every N-th (second, third, ...) element from one array to another one?
memcpy () works well but it copies EVERY element.
Is it possible to jump over several elements?
Thank you...
-
February 2nd, 2009, 12:51 PM
#2
Re: memcpy() analog
Originally Posted by squaleDOK
Hi, all.
Ask to share your opinions.
What is the best way for FAST coping every N-th (second, third, ...) element from one array to another one?
Array of what type? ints, doubles, chars, Student data, ...?
Is it possible to jump over several elements?
Yes. Write a loop to do it.
Regards,
Paul McKenzie
-
February 3rd, 2009, 06:22 AM
#3
Re: memcpy() analog
If you're using an STL container you could always create a custom iterator to increment a definable number of steps for each instance of operator++ and then use std::copy.
On the other hand, writing a simple loop could be simpler and quicker.
"It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
Richard P. Feynman
-
February 3rd, 2009, 09:00 AM
#4
Re: memcpy() analog
You could write an iterator (which is a nice idea), or you could write a loop (which is a sensible idea), or you could write a function object (for the unhinged) to pass to one of the standard algorithms such as for_each. As far as difficulty goes, a loop is the easiest, then a function object, and then an iterator. An example function object could be something like:
Code:
#include<functional> //for std::unary_function
template <typename elementType, typename ContainerType>
class CopyNth: private std::unary_function<elementType,void>
{
public:
CopyNth(size_t nthElement, ContainerType& container)
:nthelement_(nthElement)
,count_(0)
,container_(&container)
{}
void operator()(elementType& obj)
{
++count_;
if(count_ == nthelement_)
{
container_->insert(container_->end(), obj); //Make compatible with other STL containers
count_ = 0;
}
}
private:
size_t nthelement_;
size_t count_;
ContainerType* container_;
};
The call to create the above object would be something like
Code:
CopyNth<elementType, ContainerType> copyNth(nthElement, container);
for example
Code:
CopyNth<int, std::vector<int> > copyNth(3, destVec);
You could then pass it to the for_each algorithm:
Code:
std::for_each(srcVec.begin(), srcVec.end(), copyNth);
or, you could compress the previous two lines into one
Code:
std::for_each(srcVec.begin(), srcVec.end(), CopyNth<int, std::vector<int> >(3,destVec));
As a complete example:
Code:
#include<iostream>
#include<vector>
#include<algorithm> //for for_each
#include<functional> //for std::unary_function
template <typename elementType, typename ContainerType>
class CopyNth: private std::unary_function<elementType,void>
{
public:
CopyNth(size_t nthElement, ContainerType& container)
:nthelement_(nthElement)
,count_(0)
,container_(&container)
{}
void operator()(elementType& obj)
{
++count_;
if(count_ == nthelement_)
{
container_->insert(container_->end(), obj);
count_ = 0;
}
}
private:
size_t nthelement_;
size_t count_;
ContainerType* container_;
};
int main()
{
std::vector<int> srcVec;
for(int i=1; i<=100; i++)
{
srcVec.push_back(i);
}
std::vector<int> destVec;
std::for_each(srcVec.begin(), srcVec.end(), CopyNth<int, std::vector<int> >(3,destVec));
for(std::vector<int>::iterator it=destVec.begin(); it!=destVec.end(); it++)
{
std::cout << *it << std::endl;
}
system("PAUSE");
}
With regard to performance, the above idea has the possibility of having greater performance than a loop since the compiler has a greater chance to optimise an algorithm as opposed to a hand written loop (according to Effective STL anyway) - whether or not it is faster in reality is compiler dependant. That said, this particular function object has some logic in operator() which is going to slow it down a little. A loop is going to be far cleaner with respect to readability. I would expect an iterator to have similar performance to a function object.
At the end of the day, the general concensus is probably going to be to write a loop, but if performance is really an issue, it might be worth testing function objects and also iterators.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|