Dynare++: rollback the std::shared_ptr change in IntSequence

The performance cost is too high to warrant the change.
time-shift
Sébastien Villemot 2019-02-14 11:05:19 +01:00
parent 8dbc08e2c2
commit 23c9257f00
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
2 changed files with 43 additions and 34 deletions

View File

@ -13,7 +13,7 @@
$(a,b)$, then the result is $(a,a,b,b,b)$. */ $(a,b)$, then the result is $(a,a,b,b,b)$. */
IntSequence::IntSequence(const Symmetry &sy, const IntSequence &se) 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; int k = 0;
for (int i = 0; i < sy.num(); i++) for (int i = 0; i < sy.num(); i++)
@ -31,7 +31,7 @@ IntSequence::IntSequence(const Symmetry &sy, const IntSequence &se)
and one $u$. */ and one $u$. */
IntSequence::IntSequence(const Symmetry &sy, const std::vector<int> &se) IntSequence::IntSequence(const Symmetry &sy, const std::vector<int> &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], TL_RAISE_IF(sy.dimen() <= se[se.size()-1],
"Sequence is not reachable by symmetry in IntSequence()"); "Sequence is not reachable by symmetry in IntSequence()");
@ -46,7 +46,7 @@ IntSequence::IntSequence(const Symmetry &sy, const std::vector<int> &se)
sequence inserting the given number to the sequence. */ sequence inserting the given number to the sequence. */
IntSequence::IntSequence(int i, const IntSequence &s) 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; int j = 0;
while (j < s.size() && s[j] < i) 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) 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(), TL_RAISE_IF(pos < 0 || pos > s.size(),
"Wrong position for insertion IntSequence constructor"); "Wrong position for insertion IntSequence constructor");
@ -74,7 +74,7 @@ const IntSequence &
IntSequence::operator=(const IntSequence &s) IntSequence::operator=(const IntSequence &s)
{ {
TL_RAISE_IF(length != s.length, "Wrong length for in-place IntSequence::operator="); 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; return *this;
} }
@ -82,22 +82,22 @@ const IntSequence &
IntSequence::operator=(IntSequence &&s) IntSequence::operator=(IntSequence &&s)
{ {
TL_RAISE_IF(length != s.length, "Wrong length for in-place IntSequence::operator="); 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; return *this;
} }
bool bool
IntSequence::operator==(const IntSequence &s) const IntSequence::operator==(const IntSequence &s) const
{ {
return std::equal(data.get()+offset, data.get()+offset+length, return std::equal(data, data+length,
s.data.get()+s.offset, s.data.get()+s.offset+s.length); s.data, s.data+s.length);
} }
bool bool
IntSequence::operator<(const IntSequence &s) const IntSequence::operator<(const IntSequence &s) const
{ {
return std::lexicographical_compare(data.get()+offset, data.get()+offset+length, return std::lexicographical_compare(data, data+length,
s.data.get()+s.offset, s.data.get()+s.offset+s.length); s.data, s.data+s.length);
} }
bool bool
@ -127,7 +127,7 @@ IntSequence::less(const IntSequence &s) const
void void
IntSequence::sort() 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 /* Here we monotonize the sequence. If an item is less then its
@ -164,7 +164,7 @@ IntSequence::pmonotone(const Symmetry &s)
int int
IntSequence::sum() const 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 /* This returns product of subsequent items. Useful for Kronecker product
@ -173,7 +173,7 @@ IntSequence::sum() const
int int
IntSequence::mult(int i1, int i2) const 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<int>()); 1, std::multiplies<int>());
} }
@ -211,7 +211,7 @@ IntSequence::getMax() const
{ {
if (length == 0) if (length == 0)
return std::numeric_limits<int>::min(); return std::numeric_limits<int>::min();
return *std::max_element(data.get()+offset, data.get()+offset+length); return *std::max_element(data, data+length);
} }
void void
@ -233,7 +233,7 @@ IntSequence::add(int f, const IntSequence &s)
bool bool
IntSequence::isPositive() const 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; }); [](int x) { return x >= 0; });
} }
@ -242,14 +242,14 @@ IntSequence::isConstant() const
{ {
if (length < 2) if (length < 2)
return true; 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); }); [this](int x) { return x == operator[](0); });
} }
bool bool
IntSequence::isSorted() const IntSequence::isSorted() const
{ {
return std::is_sorted(data.get()+offset, data.get()+offset+length); return std::is_sorted(data, data+length);
} }
/* Debug print. */ /* Debug print. */

View File

@ -25,7 +25,6 @@
#define INT_SEQUENCE_H #define INT_SEQUENCE_H
#include <vector> #include <vector>
#include <memory>
#include <algorithm> #include <algorithm>
#include <initializer_list> #include <initializer_list>
@ -41,47 +40,53 @@
class Symmetry; class Symmetry;
class IntSequence class IntSequence
{ {
std::shared_ptr<int> data; int *data;
int length; int length;
int offset{0}; bool destroy{true};
public: public:
// Constructor allocating a given length of (uninitialized) data // Constructor allocating a given length of (uninitialized) data
explicit IntSequence(int l) 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 // Constructor allocating and then initializing all members to a given number
IntSequence(int l, int n) 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 /* Constructor using an initializer list (gives the contents of the
IntSequence, similarly to std::vector) */ IntSequence, similarly to std::vector) */
IntSequence(std::initializer_list<int> init) IntSequence(std::initializer_list<int> init)
: data{new int[init.size()], [](int *arr) { delete[] arr; }}, : data{new int[init.size()]},
length{static_cast<int>(init.size())} length{static_cast<int>(init.size())}
{ {
std::copy(init.begin(), init.end(), data.get()); std::copy(init.begin(), init.end(), data);
} }
// Copy constructor // Copy constructor
IntSequence(const IntSequence &s) 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 // 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) // Subsequence constructor (which shares the data pointer)
IntSequence(IntSequence &s, int i1, int i2) 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) // Subsequence constructor (without pointer sharing)
IntSequence(const IntSequence &s, int i1, int i2) 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 /* Constructor used for calculating implied symmetry from a more general
symmetry and one equivalence class */ symmetry and one equivalence class */
@ -95,7 +100,11 @@ public:
const IntSequence &operator=(const IntSequence &s); const IntSequence &operator=(const IntSequence &s);
const IntSequence &operator=(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;
bool bool
operator!=(const IntSequence &s) const operator!=(const IntSequence &s) const
@ -105,12 +114,12 @@ public:
int & int &
operator[](int i) operator[](int i)
{ {
return data.get()[offset+i]; return data[i];
} }
int int
operator[](int i) const operator[](int i) const
{ {
return data.get()[offset+i]; return data[i];
} }
int int
size() const size() const