CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4

Thread: memcpy() analog

  1. #1
    Join Date
    Feb 2009
    Posts
    3

    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...

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: memcpy() analog

    Quote Originally Posted by squaleDOK View Post
    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

  3. #3
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    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

  4. #4
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    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
  •  





Click Here to Expand Forum to Full Width

Featured