diff --git a/include/constantes.hpp b/include/constantes.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1f330ae9f9e4e827de7f6ef4d70ad75478f242e0
--- /dev/null
+++ b/include/constantes.hpp
@@ -0,0 +1,11 @@
+#ifndef CONSTANTES_HPP
+#define CONSTANTES_HPP
+
+#define MAX_ETATS 32
+#if MAX_ETATS > 255
+#error MAX_ETATS ne tient pas dans un unsigned char
+#endif
+
+#define MAX_VOISINS 256
+
+#endif // CONSTANTES_HPP
diff --git a/include/grid.h b/include/grid.h
index 8ba5ceea1894b15bff8f1f21f2382095e25f9957..5a6081976d2b8ca82a8df3e3424c2fdf1a21a21e 100644
--- a/include/grid.h
+++ b/include/grid.h
@@ -31,7 +31,7 @@ class Structure;
 class Grid{
     int nb_rows;
     int nb_col;
-    std::vector<unsigned int> matrix;
+    std::vector<unsigned char> matrix;
 public:
     //! \brief Constructeur par défaut, avec le nombre de ligne et de colonne souhaités
     Grid(size_t l,size_t c);
diff --git a/include/neighborhood.hpp b/include/neighborhood.hpp
index ca2e3942120a634891fefc32b3f1f96cb3841d0d..527b1ac271e4620f047f7027a8e3a570199cccf9 100644
--- a/include/neighborhood.hpp
+++ b/include/neighborhood.hpp
@@ -17,9 +17,11 @@ Cette classe représente le voisinage d'une cellule.
 #include <utility>
 #include <string>
 #include <algorithm>
+#include <cstring>
 
 #include "coord.hpp"
 #include "state.hpp"
+#include "constantes.hpp"
 
     using namespace std;
 
@@ -38,18 +40,27 @@ public:
 
 //! \brief Classe représentant un voisinage, c'est à dire une liste de cellules dont leur état et leur position.
 class Neighborhood {
-    //! \brief vector de voisins contenant la position relative et l'état du voisin
-    mutable vector<pair<Coord, unsigned int>> neighborPositions;
-    //! \brief Contient le nombre de voisins d'état i : counts[i] contient le nb de voisins d'état i, ou 0 si i >= counts.size()
-    std::vector<unsigned> counts;
+    //! \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;
+    };
+
+    //! \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
+    unsigned char counts[MAX_ETATS];
+    //! \brief Nombre de voisins
+    unsigned int neighbors;
     mutable bool sorted;
+    //! \brief Tableau contenant la liste des voisins
+    mutable Cell neighborPositions[MAX_VOISINS];
 
 public:
     //! \brief Initialisation du Neighborhood
     Neighborhood()
     {
-        neighborPositions.reserve(8);
-        counts.reserve(8);
+        memset(counts, 0, MAX_ETATS);
+        neighbors = 0;
         sorted = false;
     }
 
@@ -58,7 +69,7 @@ public:
     //! \return Le nombre de voisin
     unsigned int getNb(unsigned int s) const
     {
-        if (s >= counts.size())
+        if (s >= MAX_ETATS)
             return 0;
         else
             return counts[s];
@@ -68,12 +79,13 @@ public:
     //! \brief Ajoute un voisin au vecteur des voisins. Prend une coordonnée et un état en paramètre
     //! \param Coord, State : coordonée relative et état du voisin
     //! \pre La coord ne doit pas déjà exister
-    void addNeighbor(Coord c, unsigned int s) {
+    void addNeighbor(Coord c, unsigned char s) {
+        if (s >= MAX_ETATS)
+            throw NeighborhoodException("Valeur d'état supérieure à l'état maximal");
+
         sorted = false;
-        neighborPositions.push_back({c,s});
-            if (s >= counts.size())
-                counts.resize(s+1, 0);
-            ++counts[s];
+        neighborPositions[neighbors++] = {c,s};
+        ++counts[s];
     }
 
     //! \brief Retourne une copie du voisinage, miroir selon l'axe vertical.
@@ -85,23 +97,23 @@ public:
 
     //! \brief Retourne le nombre de voisins dans le Neighborhood.
     unsigned size() const
-    { return neighborPositions.size(); }
+    { return neighbors; }
 
     //! \brief Retourne la cellule numéro i (index allant de 0 à size()-1, permettant d'indexer les cellules indépendamment de leur position
-    pair<Coord, unsigned int> neighbor_at_index(unsigned i) const
+    pair<Coord, unsigned char> neighbor_at_index(unsigned i) const
     {
         if (i >= size())
             throw NeighborhoodException("Index invalide\n");
         if (!sorted)
         {
-            std::sort(neighborPositions.begin(), neighborPositions.end(),
-                      [](const pair<Coord, unsigned int>& lhs, const pair<Coord, unsigned int>& rhs)
+            std::sort(std::begin(neighborPositions), std::begin(neighborPositions) + neighbors,
+                      [](const Cell& lhs, const Cell& rhs)
                       {
-                          return lhs.first < rhs.first;
+                          return lhs.pos < rhs.pos;
                       });
             sorted = true;
         }
-        return neighborPositions[i];
+        return {neighborPositions[i].pos, neighborPositions[i].state};
     }
 };
 
diff --git a/src/neighborhood.cpp b/src/neighborhood.cpp
index 0792e12e15c2a74414bd0891646e8ac82e06e45f..ce235e7f8f7e02ef272c4f1ca21d34f3a3649f1d 100644
--- a/src/neighborhood.cpp
+++ b/src/neighborhood.cpp
@@ -3,9 +3,10 @@
 Neighborhood Neighborhood::flip_vertically() const
 {
     Neighborhood n;
-    for (const auto& val : neighborPositions)
+    for (unsigned i = 0; i < size(); ++i)
     {
-        n.addNeighbor(Coord{val.first.x, -val.first.y}, val.second);
+        const auto& val = neighborPositions[i];
+        n.addNeighbor(Coord{val.pos.x, -val.pos.y}, val.state);
     }
     return n;
 }
@@ -13,9 +14,10 @@ Neighborhood Neighborhood::flip_vertically() const
 Neighborhood Neighborhood::flip_horizontally() const
 {
     Neighborhood n;
-    for (const auto& val : neighborPositions)
+    for (unsigned i = 0; i < size(); ++i)
     {
-        n.addNeighbor(Coord{-val.first.x, val.first.y}, val.second);
+        const auto& val = neighborPositions[i];
+        n.addNeighbor(Coord{-val.pos.x, val.pos.y}, val.state);
     }
     return n;
 }
@@ -23,9 +25,10 @@ Neighborhood Neighborhood::flip_horizontally() const
 Neighborhood Neighborhood::rotate90() const
 {
     Neighborhood n;
-    for (const auto& val : neighborPositions)
+    for (unsigned i = 0; i < size(); ++i)
     {
-        n.addNeighbor(Coord{-val.first.y, val.first.x}, val.second);
+        const auto& val = neighborPositions[i];
+        n.addNeighbor(Coord{-val.pos.y, val.pos.x}, val.state);
     }
     return n;
 }
diff --git a/src/src.pro b/src/src.pro
index a46c4dc112379e47b3ed5c0cecd48c4f61b5f751..1de401f2e723c89be433ad9825ff4781780d20f9 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -6,7 +6,7 @@ CONFIG += c++14
 TEMPLATE = app
 
 # Optimisations, flag pour garder les infos de debug
-QMAKE_CXXFLAGS += -O2 -g
+QMAKE_CXXFLAGS += -O3 -g
 
 # You can make your code fail to compile if it uses deprecated APIs.
 # In order to do so, uncomment the following line.
@@ -69,6 +69,7 @@ HEADERS += \
     ../include/stateColor.hpp \
     ../include/state.hpp \
     ../include/history.h \
+    ../include/constantes.hpp \
     ../include/structurelibraryview.hpp \
     ../include/transitionrule.hpp \
     ../include/transition_rules/circulartransition.hpp \