More efficient Python slicing
Call reserve for container types that support it to avoid repeated memory reallocations for new slices or slices that grow in size.
This commit is contained in:
parent
5ebf1cfa5d
commit
5abb3e8008
6 changed files with 45 additions and 0 deletions
|
|
@ -262,6 +262,13 @@ namespace swig {
|
||||||
seq->erase(position);
|
seq->erase(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class Sequence>
|
||||||
|
struct traits_reserve {
|
||||||
|
static void reserve(Sequence & /*seq*/, typename Sequence::size_type /*n*/) {
|
||||||
|
// This should be specialized for types that support reserve
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <class Sequence, class Difference>
|
template <class Sequence, class Difference>
|
||||||
inline Sequence*
|
inline Sequence*
|
||||||
getslice(const Sequence* self, Difference i, Difference j, Py_ssize_t step) {
|
getslice(const Sequence* self, Difference i, Difference j, Py_ssize_t step) {
|
||||||
|
|
@ -279,6 +286,7 @@ namespace swig {
|
||||||
return new Sequence(sb, se);
|
return new Sequence(sb, se);
|
||||||
} else {
|
} else {
|
||||||
Sequence *sequence = new Sequence();
|
Sequence *sequence = new Sequence();
|
||||||
|
swig::traits_reserve<Sequence>::reserve(*sequence, (jj - ii + step - 1) / step);
|
||||||
typename Sequence::const_iterator it = sb;
|
typename Sequence::const_iterator it = sb;
|
||||||
while (it!=se) {
|
while (it!=se) {
|
||||||
sequence->push_back(*it);
|
sequence->push_back(*it);
|
||||||
|
|
@ -289,6 +297,7 @@ namespace swig {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Sequence *sequence = new Sequence();
|
Sequence *sequence = new Sequence();
|
||||||
|
swig::traits_reserve<Sequence>::reserve(*sequence, (ii - jj - step - 1) / -step);
|
||||||
typename Sequence::const_reverse_iterator sb = self->rbegin();
|
typename Sequence::const_reverse_iterator sb = self->rbegin();
|
||||||
typename Sequence::const_reverse_iterator se = self->rbegin();
|
typename Sequence::const_reverse_iterator se = self->rbegin();
|
||||||
std::advance(sb,size-ii-1);
|
std::advance(sb,size-ii-1);
|
||||||
|
|
@ -315,6 +324,7 @@ namespace swig {
|
||||||
size_t ssize = jj - ii;
|
size_t ssize = jj - ii;
|
||||||
if (ssize <= is.size()) {
|
if (ssize <= is.size()) {
|
||||||
// expanding/staying the same size
|
// expanding/staying the same size
|
||||||
|
swig::traits_reserve<Sequence>::reserve(*self, self->size() - ssize + is.size());
|
||||||
typename Sequence::iterator sb = self->begin();
|
typename Sequence::iterator sb = self->begin();
|
||||||
typename InputSeq::const_iterator isit = is.begin();
|
typename InputSeq::const_iterator isit = is.begin();
|
||||||
std::advance(sb,ii);
|
std::advance(sb,ii);
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class K, class T>
|
||||||
|
struct traits_reserve<std::unordered_map<K,T> > {
|
||||||
|
static void reserve(std::unordered_map<K,T> &seq, typename std::unordered_map<K,T>::size_type n) {
|
||||||
|
seq.reserve(n);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <class K, class T>
|
template <class K, class T>
|
||||||
struct traits_asptr<std::unordered_map<K,T> > {
|
struct traits_asptr<std::unordered_map<K,T> > {
|
||||||
typedef std::unordered_map<K,T> unordered_map_type;
|
typedef std::unordered_map<K,T> unordered_map_type;
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class K, class T>
|
||||||
|
struct traits_reserve<std::unordered_multimap<K,T> > {
|
||||||
|
static void reserve(std::unordered_multimap<K,T> &seq, typename std::unordered_multimap<K,T>::size_type n) {
|
||||||
|
seq.reserve(n);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <class K, class T>
|
template <class K, class T>
|
||||||
struct traits_asptr<std::unordered_multimap<K,T> > {
|
struct traits_asptr<std::unordered_multimap<K,T> > {
|
||||||
typedef std::unordered_multimap<K,T> unordered_multimap_type;
|
typedef std::unordered_multimap<K,T> unordered_multimap_type;
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct traits_reserve<std::unordered_multiset<T> > {
|
||||||
|
static void reserve(std::unordered_multiset<T> &seq, typename std::unordered_multiset<T>::size_type n) {
|
||||||
|
seq.reserve(n);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct traits_asptr<std::unordered_multiset<T> > {
|
struct traits_asptr<std::unordered_multiset<T> > {
|
||||||
static int asptr(PyObject *obj, std::unordered_multiset<T> **m) {
|
static int asptr(PyObject *obj, std::unordered_multiset<T> **m) {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct traits_reserve<std::unordered_set<T> > {
|
||||||
|
static void reserve(std::unordered_set<T> &seq, typename std::unordered_set<T>::size_type n) {
|
||||||
|
seq.reserve(n);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct traits_asptr<std::unordered_set<T> > {
|
struct traits_asptr<std::unordered_set<T> > {
|
||||||
static int asptr(PyObject *obj, std::unordered_set<T> **s) {
|
static int asptr(PyObject *obj, std::unordered_set<T> **s) {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,13 @@
|
||||||
%fragment("StdVectorTraits","header",fragment="StdSequenceTraits")
|
%fragment("StdVectorTraits","header",fragment="StdSequenceTraits")
|
||||||
%{
|
%{
|
||||||
namespace swig {
|
namespace swig {
|
||||||
|
template <class T>
|
||||||
|
struct traits_reserve<std::vector<T> > {
|
||||||
|
static void reserve(std::vector<T> &seq, typename std::vector<T>::size_type n) {
|
||||||
|
seq.reserve(n);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct traits_asptr<std::vector<T> > {
|
struct traits_asptr<std::vector<T> > {
|
||||||
static int asptr(PyObject *obj, std::vector<T> **vec) {
|
static int asptr(PyObject *obj, std::vector<T> **vec) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue