Skip to content
Snippets Groups Projects
Commit 2660013d authored by Yann Boucher's avatar Yann Boucher
Browse files

3x Performance improvements to Neighborhood and Nonisotropictransition

parent ee2d58f8
No related branches found
No related tags found
No related merge requests found
...@@ -18,6 +18,7 @@ Cette classe représente le voisinage d'une cellule. ...@@ -18,6 +18,7 @@ Cette classe représente le voisinage d'une cellule.
#include <string> #include <string>
#include <algorithm> #include <algorithm>
#include <cstring> #include <cstring>
#include <cstdint>
#include "coord.hpp" #include "coord.hpp"
#include "state.hpp" #include "state.hpp"
...@@ -43,8 +44,8 @@ class Neighborhood { ...@@ -43,8 +44,8 @@ class Neighborhood {
//! \brief struct nécéssaire pour éviter l'initalisation par zéro coûteuse d'un std::pair //! \brief struct nécéssaire pour éviter l'initalisation par zéro coûteuse d'un std::pair
struct Cell struct Cell
{ {
Coord pos; int8_t pos_x, pos_y;
unsigned char state; uint8_t state;
}; };
//! \brief Contient le nombre de voisins d'état i : counts[i] contient le nb de voisins d'état i, ou 0 si i >= MAX_ETATS //! \brief Contient le nombre de voisins d'état i : counts[i] contient le nb de voisins d'état i, ou 0 si i >= MAX_ETATS
...@@ -59,11 +60,26 @@ public: ...@@ -59,11 +60,26 @@ public:
//! \brief Initialisation du Neighborhood //! \brief Initialisation du Neighborhood
Neighborhood() Neighborhood()
{ {
memset(counts, 0, MAX_ETATS); memset(counts, 0, MAX_ETATS*sizeof(unsigned char));
neighbors = 0; neighbors = 0;
sorted = false; sorted = false;
} }
//! \brief Initialisation par copie
Neighborhood(const Neighborhood& other)
{
*this = other;
}
//! \brief Affectation par copie
Neighborhood& operator=(const Neighborhood& other)
{
memcpy(counts, other.counts, MAX_ETATS*sizeof(unsigned char));
memcpy(neighborPositions, other.neighborPositions, other.neighbors*sizeof(Cell));
neighbors = other.neighbors;
sorted = other.sorted;
return *this;
}
//! \brief Retourne le nombre de voisin ayant l'état définit en paramètre //! \brief Retourne le nombre de voisin ayant l'état définit en paramètre
//! \param State : Etat des voisins à rechercher //! \param State : Etat des voisins à rechercher
//! \return Le nombre de voisin //! \return Le nombre de voisin
...@@ -84,7 +100,7 @@ public: ...@@ -84,7 +100,7 @@ public:
throw NeighborhoodException("Valeur d'état supérieure à l'état maximal"); throw NeighborhoodException("Valeur d'état supérieure à l'état maximal");
sorted = false; sorted = false;
neighborPositions[neighbors++] = {c,s}; neighborPositions[neighbors++] = {(int8_t)c.x, (int8_t)c.y, s};
++counts[s]; ++counts[s];
} }
...@@ -109,11 +125,11 @@ public: ...@@ -109,11 +125,11 @@ public:
std::sort(std::begin(neighborPositions), std::begin(neighborPositions) + neighbors, std::sort(std::begin(neighborPositions), std::begin(neighborPositions) + neighbors,
[](const Cell& lhs, const Cell& rhs) [](const Cell& lhs, const Cell& rhs)
{ {
return lhs.pos < rhs.pos; return Coord{(int)lhs.pos_x, (int)lhs.pos_y} < Coord{(int)rhs.pos_x, (int)rhs.pos_y};
}); });
sorted = true; sorted = true;
} }
return {neighborPositions[i].pos, neighborPositions[i].state}; return {Coord{(int)neighborPositions[i].pos_x,(int)neighborPositions[i].pos_y}, neighborPositions[i].state};
} }
}; };
......
...@@ -99,7 +99,7 @@ int eval_math(const std::string &in_expr, const std::map<std::string, int> &vari ...@@ -99,7 +99,7 @@ int eval_math(const std::string &in_expr, const std::map<std::string, int> &vari
{ {
std::string expr = in_expr; std::string expr = in_expr;
// remove whitespace out of the equation altogether // remove whitespace out of the equation altogether
expr.erase(std::remove_if(expr.begin(), expr.end(), ::isspace), expr.end()); expr.erase(std::remove_if(expr.begin(), expr.end(), ::isspace), expr.end());
std::vector<rpl_token_t> rpl_stack; std::vector<rpl_token_t> rpl_stack;
std::stack<char> op_stack; std::stack<char> op_stack;
......
...@@ -6,7 +6,7 @@ Neighborhood Neighborhood::flip_vertically() const ...@@ -6,7 +6,7 @@ Neighborhood Neighborhood::flip_vertically() const
for (unsigned i = 0; i < size(); ++i) for (unsigned i = 0; i < size(); ++i)
{ {
const auto& val = neighborPositions[i]; const auto& val = neighborPositions[i];
n.addNeighbor(Coord{val.pos.x, -val.pos.y}, val.state); n.addNeighbor(Coord{val.pos_x, -val.pos_y}, val.state);
} }
return n; return n;
} }
...@@ -17,19 +17,20 @@ Neighborhood Neighborhood::flip_horizontally() const ...@@ -17,19 +17,20 @@ Neighborhood Neighborhood::flip_horizontally() const
for (unsigned i = 0; i < size(); ++i) for (unsigned i = 0; i < size(); ++i)
{ {
const auto& val = neighborPositions[i]; const auto& val = neighborPositions[i];
n.addNeighbor(Coord{-val.pos.x, val.pos.y}, val.state); n.addNeighbor(Coord{-val.pos_x, val.pos_y}, val.state);
} }
return n; return n;
} }
Neighborhood Neighborhood::rotate90() const Neighborhood Neighborhood::rotate90() const
{ {
Neighborhood n; Neighborhood n = *this;
for (unsigned i = 0; i < size(); ++i) for (unsigned i = 0; i < neighbors; ++i)
{ {
const auto& val = neighborPositions[i]; n.neighborPositions[i].pos_x = -this->neighborPositions[i].pos_y;
n.addNeighbor(Coord{-val.pos.y, val.pos.x}, val.state); n.neighborPositions[i].pos_y = this->neighborPositions[i].pos_x;
} }
return n; return n;
} }
...@@ -61,27 +61,29 @@ bool NonIsotropicRuleEntry::accept(unsigned initial_state, const Neighborhood &n ...@@ -61,27 +61,29 @@ bool NonIsotropicRuleEntry::accept(unsigned initial_state, const Neighborhood &n
if (!m_initial_state_is_variable && initial_state != m_initial_state) if (!m_initial_state_is_variable && initial_state != m_initial_state)
return false; return false;
std::vector<Neighborhood> neighborhoods_to_test; unsigned n_count = 0;
neighborhoods_to_test.push_back(neighborhood); Neighborhood neighborhoods_to_test[8];
if (m_vertical_sym) neighborhoods_to_test[n_count++] = neighborhood;
neighborhoods_to_test.push_back(neighborhood.flip_vertically());
if (m_horizontal_sym)
neighborhoods_to_test.push_back(neighborhood.flip_horizontally());
if (m_vertical_sym && m_horizontal_sym)
neighborhoods_to_test.push_back(neighborhood.flip_vertically().flip_horizontally());
if (m_rotate4) if (m_rotate4)
{ {
Neighborhood to_rotate = neighborhood;
for (unsigned i = 0; i < 3; ++i) for (unsigned i = 0; i < 3; ++i)
{ {
to_rotate = to_rotate.rotate90(); neighborhoods_to_test[n_count] = neighborhoods_to_test[n_count-1].rotate90();
neighborhoods_to_test.push_back(to_rotate); ++n_count;
} }
} }
if (m_vertical_sym)
neighborhoods_to_test[n_count++] = neighborhood.flip_vertically();
if (m_horizontal_sym)
neighborhoods_to_test[n_count++] = neighborhood.flip_horizontally();
if (m_vertical_sym && m_horizontal_sym)
neighborhoods_to_test[n_count++] = neighborhood.flip_vertically().flip_horizontally();
bool entry_accepted = false; bool entry_accepted = false;
for (const auto& n : neighborhoods_to_test) for (unsigned k = 0; k < n_count; ++k)
{ {
const auto& n = neighborhoods_to_test[k];
bool constraint_accepted = true; bool constraint_accepted = true;
for (unsigned i = 0; i < m_constraints.size(); ++i) for (unsigned i = 0; i < m_constraints.size(); ++i)
{ {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment