From 23c9257f008f96727f2421ef1e8d6648efcd425f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Thu, 14 Feb 2019 11:05:19 +0100 Subject: [PATCH] Dynare++: rollback the std::shared_ptr change in IntSequence The performance cost is too high to warrant the change. --- dynare++/tl/cc/int_sequence.cc | 34 +++++++++++++-------------- dynare++/tl/cc/int_sequence.hh | 43 ++++++++++++++++++++-------------- 2 files changed, 43 insertions(+), 34 deletions(-) diff --git a/dynare++/tl/cc/int_sequence.cc b/dynare++/tl/cc/int_sequence.cc index 2dad701d9..f50d0f80e 100644 --- a/dynare++/tl/cc/int_sequence.cc +++ b/dynare++/tl/cc/int_sequence.cc @@ -13,7 +13,7 @@ $(a,b)$, then the result is $(a,a,b,b,b)$. */ IntSequence::IntSequence(const Symmetry &sy, const IntSequence &se) - : data{new int[sy.dimen()], [](int *arr) { delete[] arr; }}, length{sy.dimen()} + : data{new int[sy.dimen()]}, length{sy.dimen()} { int k = 0; for (int i = 0; i < sy.num(); i++) @@ -31,7 +31,7 @@ IntSequence::IntSequence(const Symmetry &sy, const IntSequence &se) and one $u$. */ IntSequence::IntSequence(const Symmetry &sy, const std::vector &se) - : data{new int[sy.num()], [](int *arr) { delete[] arr; }}, length{sy.num()} + : data{new int[sy.num()]}, length{sy.num()} { TL_RAISE_IF(sy.dimen() <= se[se.size()-1], "Sequence is not reachable by symmetry in IntSequence()"); @@ -46,7 +46,7 @@ IntSequence::IntSequence(const Symmetry &sy, const std::vector &se) sequence inserting the given number to the sequence. */ IntSequence::IntSequence(int i, const IntSequence &s) - : data{new int[s.size()+1], [](int *arr) { delete[] arr; }}, length{s.size()+1} + : data{new int[s.size()+1]}, length{s.size()+1} { int j = 0; while (j < s.size() && s[j] < i) @@ -59,7 +59,7 @@ IntSequence::IntSequence(int i, const IntSequence &s) } IntSequence::IntSequence(int i, const IntSequence &s, int pos) - : data{new int[s.size()+1], [](int *arr) { delete[] arr; }}, length{s.size()+1} + : data{new int[s.size()+1]}, length{s.size()+1} { TL_RAISE_IF(pos < 0 || pos > s.size(), "Wrong position for insertion IntSequence constructor"); @@ -74,7 +74,7 @@ const IntSequence & IntSequence::operator=(const IntSequence &s) { TL_RAISE_IF(length != s.length, "Wrong length for in-place IntSequence::operator="); - std::copy_n(s.data.get()+s.offset, length, data.get()+offset); + std::copy_n(s.data, length, data); return *this; } @@ -82,22 +82,22 @@ const IntSequence & IntSequence::operator=(IntSequence &&s) { TL_RAISE_IF(length != s.length, "Wrong length for in-place IntSequence::operator="); - std::copy_n(s.data.get()+s.offset, length, data.get()+offset); + std::copy_n(s.data, length, data); return *this; } bool IntSequence::operator==(const IntSequence &s) const { - return std::equal(data.get()+offset, data.get()+offset+length, - s.data.get()+s.offset, s.data.get()+s.offset+s.length); + return std::equal(data, data+length, + s.data, s.data+s.length); } bool IntSequence::operator<(const IntSequence &s) const { - return std::lexicographical_compare(data.get()+offset, data.get()+offset+length, - s.data.get()+s.offset, s.data.get()+s.offset+s.length); + return std::lexicographical_compare(data, data+length, + s.data, s.data+s.length); } bool @@ -127,7 +127,7 @@ IntSequence::less(const IntSequence &s) const void IntSequence::sort() { - std::sort(data.get()+offset, data.get()+offset+length); + std::sort(data, data+length); } /* Here we monotonize the sequence. If an item is less then its @@ -164,7 +164,7 @@ IntSequence::pmonotone(const Symmetry &s) int IntSequence::sum() const { - return std::accumulate(data.get()+offset, data.get()+offset+length, 0); + return std::accumulate(data, data+length, 0); } /* This returns product of subsequent items. Useful for Kronecker product @@ -173,7 +173,7 @@ IntSequence::sum() const int IntSequence::mult(int i1, int i2) const { - return std::accumulate(data.get()+offset+i1, data.get()+offset+i2, + return std::accumulate(data+i1, data+i2, 1, std::multiplies()); } @@ -211,7 +211,7 @@ IntSequence::getMax() const { if (length == 0) return std::numeric_limits::min(); - return *std::max_element(data.get()+offset, data.get()+offset+length); + return *std::max_element(data, data+length); } void @@ -233,7 +233,7 @@ IntSequence::add(int f, const IntSequence &s) bool IntSequence::isPositive() const { - return std::all_of(data.get()+offset, data.get()+offset+length, + return std::all_of(data, data+length, [](int x) { return x >= 0; }); } @@ -242,14 +242,14 @@ IntSequence::isConstant() const { if (length < 2) return true; - return std::all_of(data.get()+offset+1, data.get()+offset+length, + return std::all_of(data+1, data+length, [this](int x) { return x == operator[](0); }); } bool IntSequence::isSorted() const { - return std::is_sorted(data.get()+offset, data.get()+offset+length); + return std::is_sorted(data, data+length); } /* Debug print. */ diff --git a/dynare++/tl/cc/int_sequence.hh b/dynare++/tl/cc/int_sequence.hh index 58dfd7e64..44bf0b3c9 100644 --- a/dynare++/tl/cc/int_sequence.hh +++ b/dynare++/tl/cc/int_sequence.hh @@ -25,7 +25,6 @@ #define INT_SEQUENCE_H #include -#include #include #include @@ -41,47 +40,53 @@ class Symmetry; class IntSequence { - std::shared_ptr data; + int *data; int length; - int offset{0}; + bool destroy{true}; public: // Constructor allocating a given length of (uninitialized) data explicit IntSequence(int l) - : data{new int[l], [](int *arr) { delete[] arr; }}, length{l} + : data{new int[l]}, length{l} { } // Constructor allocating and then initializing all members to a given number IntSequence(int l, int n) - : data{new int[l], [](int *arr) { delete[] arr; }}, length{l} + : data{new int[l]}, length{l} { - std::fill_n(data.get(), length, n); + std::fill_n(data, length, n); } /* Constructor using an initializer list (gives the contents of the IntSequence, similarly to std::vector) */ IntSequence(std::initializer_list init) - : data{new int[init.size()], [](int *arr) { delete[] arr; }}, + : data{new int[init.size()]}, length{static_cast(init.size())} { - std::copy(init.begin(), init.end(), data.get()); + std::copy(init.begin(), init.end(), data); } // Copy constructor IntSequence(const IntSequence &s) - : data{new int[s.length], [](int *arr) { delete[] arr; }}, length{s.length} + : data{new int[s.length]}, length{s.length} { - std::copy_n(s.data.get()+s.offset, length, data.get()); + std::copy_n(s.data, length, data); } // Move constructor - IntSequence(IntSequence &&s) = default; + IntSequence(IntSequence &&s) + : data{s.data}, length{s.length}, destroy{s.destroy} + { + s.data = nullptr; + s.length = 0; + s.destroy = false; + } // Subsequence constructor (which shares the data pointer) IntSequence(IntSequence &s, int i1, int i2) - : data{s.data}, length{i2-i1}, offset{s.offset+i1} + : data{s.data+i1}, length{i2-i1}, destroy{false} { } // Subsequence constructor (without pointer sharing) IntSequence(const IntSequence &s, int i1, int i2) - : data{new int[i2-i1], [](int *arr) { delete[] arr; }}, length{i2-i1} + : data{new int[i2-i1]}, length{i2-i1} { - std::copy_n(s.data.get()+s.offset+i1, length, data.get()); + std::copy_n(s.data+i1, length, data); } /* Constructor used for calculating implied symmetry from a more general symmetry and one equivalence class */ @@ -95,7 +100,11 @@ public: const IntSequence &operator=(const IntSequence &s); const IntSequence &operator=(IntSequence &&s); - virtual ~IntSequence() = default; + virtual ~IntSequence() + { + if (destroy) + delete[] data; + } bool operator==(const IntSequence &s) const; bool operator!=(const IntSequence &s) const @@ -105,12 +114,12 @@ public: int & operator[](int i) { - return data.get()[offset+i]; + return data[i]; } int operator[](int i) const { - return data.get()[offset+i]; + return data[i]; } int size() const