Commit 2660013d authored by Yann Boucher's avatar Yann Boucher
Browse files

3x Performance improvements to Neighborhood and Nonisotropictransition

parent ee2d58f8
......@@ -18,6 +18,7 @@ Cette classe représente le voisinage d'une cellule.
#include <string>
#include <algorithm>
#include <cstring>
#include <cstdint>
#include "coord.hpp"
#include "state.hpp"
......@@ -43,8 +44,8 @@ class Neighborhood {
//! \brief struct nécéssaire pour éviter l'initalisation par zéro coûteuse d'un std::pair
struct Cell
{
Coord pos;
unsigned char state;
int8_t pos_x, pos_y;
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
......@@ -59,11 +60,26 @@ public:
//! \brief Initialisation du Neighborhood
Neighborhood()
{
memset(counts, 0, MAX_ETATS);
memset(counts, 0, MAX_ETATS*sizeof(unsigned char));
neighbors = 0;
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
//! \param State : Etat des voisins à rechercher
//! \return Le nombre de voisin
......@@ -84,7 +100,7 @@ public:
throw NeighborhoodException("Valeur d'état supérieure à l'état maximal");
sorted = false;
neighborPositions[neighbors++] = {c,s};
neighborPositions[neighbors++] = {(int8_t)c.x, (int8_t)c.y, s};
++counts[s];
}
......@@ -109,11 +125,11 @@ public:
std::sort(std::begin(neighborPositions), std::begin(neighborPositions) + neighbors,
[](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;
}
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
{
std::string expr = in_expr;
// 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::stack<char> op_stack;
......
......@@ -6,7 +6,7 @@ Neighborhood Neighborhood::flip_vertically() const
for (unsigned i = 0; i < size(); ++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;
}
......@@ -17,19 +17,20 @@ Neighborhood Neighborhood::flip_horizontally() const
for (unsigned i = 0; i < size(); ++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;
}
Neighborhood Neighborhood::rotate90() const
{
Neighborhood n;
for (unsigned i = 0; i < size(); ++i)
Neighborhood n = *this;
for (unsigned i = 0; i < neighbors; ++i)
{
const auto& val = neighborPositions[i];
n.addNeighbor(Coord{-val.pos.y, val.pos.x}, val.state);
n.neighborPositions[i].pos_x = -this->neighborPositions[i].pos_y;
n.neighborPositions[i].pos_y = this->neighborPositions[i].pos_x;
}
return 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)
return false;
std::vector<Neighborhood> neighborhoods_to_test;
neighborhoods_to_test.push_back(neighborhood);
if (m_vertical_sym)
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());
unsigned n_count = 0;
Neighborhood neighborhoods_to_test[8];
neighborhoods_to_test[n_count++] = neighborhood;
if (m_rotate4)
{
Neighborhood to_rotate = neighborhood;
for (unsigned i = 0; i < 3; ++i)
{
to_rotate = to_rotate.rotate90();
neighborhoods_to_test.push_back(to_rotate);
neighborhoods_to_test[n_count] = neighborhoods_to_test[n_count-1].rotate90();
++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;
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;
for (unsigned i = 0; i < m_constraints.size(); ++i)
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment