aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar David Leverton <levertond@googlemail.com> 2007-08-21 18:10:29 +0000
committerAvatar David Leverton <levertond@googlemail.com> 2007-08-21 18:10:29 +0000
commit3682d0526f30e42eafad9b4a68a381c066ace2a5 (patch)
tree8fcff91456b06eb33605cf930143c8666fb96a34
parentce05f6b7ce5a001829ee6adf718f494125d7ce95 (diff)
downloadpaludis-3682d0526f30e42eafad9b4a68a381c066ace2a5.tar.gz
paludis-3682d0526f30e42eafad9b4a68a381c066ace2a5.tar.xz
Optimise for random-access iterators.
-rw-r--r--paludis/util/parallel_for_each.hh32
1 files changed, 28 insertions, 4 deletions
diff --git a/paludis/util/parallel_for_each.hh b/paludis/util/parallel_for_each.hh
index a1eccbe..10541c7 100644
--- a/paludis/util/parallel_for_each.hh
+++ b/paludis/util/parallel_for_each.hh
@@ -24,6 +24,7 @@
#include <paludis/util/sequence.hh>
#include <paludis/util/make_shared_ptr.hh>
#include <paludis/util/tr1_memory.hh>
+#include <paludis/util/tr1_type_traits.hh>
#ifndef PALUDIS_ENABLE_THREADS
# include <algorithm>
@@ -31,16 +32,39 @@
namespace paludis
{
+ template <typename I_, bool is_random_access_>
+ struct CappedAdvance
+ {
+ typedef typename std::iterator_traits<I_>::difference_type Distance;
+ static void advance(I_ & cur, const I_ & end, Distance d)
+ {
+ for (Distance x(0) ; x < d ; ++x, ++cur)
+ if (cur == end)
+ break;
+ }
+ };
+
+ template <typename I_>
+ struct CappedAdvance<I_, true>
+ {
+ typedef typename std::iterator_traits<I_>::difference_type Distance;
+ static void advance(I_ & cur, const I_ & end, Distance d)
+ {
+ if (end - cur > d)
+ cur += d;
+ else
+ cur = end;
+ }
+ };
+
template <typename I_, typename P_>
void parallel_for_each_worker(I_ cur, const I_ & end, const unsigned partition_size, const P_ & op)
{
while (cur != end)
{
op(*cur);
-
- for (unsigned x(0) ; x < partition_size ; ++x, ++cur)
- if (cur == end)
- break;
+ CappedAdvance<I_, tr1::is_same<typename std::iterator_traits<I_>::iterator_category,
+ std::random_access_iterator_tag>::value>::advance(cur, end, partition_size);
}
}