J'ai des données qui sont N par 4 que je repousse les données comme suit.
vector<vector<int>> a; a.resize(13000,vector<int>(4));
N serait inférieur à 13000. Afin d'éviter une réallocation inutile, je voudrais réserver 13000 par 4 espaces à l'avance.
Après avoir lu plusieurs articles connexes sur ce sujet (par exemple, Comment réserver un vecteur multidimensionnel? ) , Je sais que ce qui suit fera le travail. Mais j'aimerais le faire avec reserve () ou toute fonction similaire s'il y en a, pour pouvoir utiliser push_back()
.
vector<vector<int>> a(13000,vector<int>(4);
ou
vector<vector<int>> a; for(some loop){ ... a.push_back(vector<int>(4){val1,val2,val3,val4}); }
Comment puis-je simplement réserver de la mémoire sans augmenter la taille du vecteur?
3 Réponses :
Vous avez déjà répondu à votre propre question.
Il existe une fonction vector :: reserve
qui fait exactement ce que vous voulez.
vector<vector<int>> a; a.reserve(N); for(some loop){ ... a.push_back(vector<int>(4){val1,val2,val3,val4}); }
Cela réservera de la mémoire pour s'adapter à N
fois vector
. Notez que la taille réelle du vector
interne n'est pas pertinente à ce stade car les données d'un vecteur sont allouées ailleurs, seuls un pointeur et une certaine comptabilité sont stockés dans le std réel :: vector
-class.
Si vos données sont garanties N x 4, vous ne voulez pas utiliser un std::vector
, mais plutôt quelque chose comme std :: vector
.
Pourquoi?
std :: array code>
est conçu pour des séquences contiguës de données de largeur fixe. (Cela ouvre également le potentiel pour plus d'optimisations de performances par le compilateur, bien que cela dépende exactement de ce que vous écrivez.) Cela dit, la réponse de @ pasbi est correcte: vous pouvez utiliser std :: vector :: reserve ()
pour allouer de l'espace pour votre vecteur externe avant d'insérer des éléments réels (à la fois pour les vecteurs-de-vecteurs et pour les vecteurs-de-tableaux). De plus, plus tard, vous pouvez utiliser std :: vector :: shrink_to_fit ()
si vous avez fini par en insérer beaucoup moins que ce que vous aviez prévu.
Enfin, une autre option consiste à utiliser un gsl :: multispan
et un pré- allouez-lui de la mémoire (GSL est la Library ).
Parfait! Merci beaucoup!
Remarque: cette réponse n'est ici que par souci d'exhaustivité au cas où vous auriez un problème similaire avec une taille inconnue; garder un std :: vector
dans votre cas fera parfaitement l'affaire.
Pour reprendre la réponse d'einpoklum, et au cas où vous ne l'auriez pas trouvé ceci plus tôt, c'est presque toujours une mauvaise idée d'avoir des std :: vectors imbriqués, à cause de la disposition de la mémoire dont il a parlé. Chaque vecteur interne allouera son propre bloc de données, qui ne sera pas (nécessairement) contigu aux autres, ce qui produira des erreurs de cache.
De préférence, soit:
std::vector
de taille N x M. // Before: int& element = vec[nIndex][mIndex]; // After: int& element = vec[mIndex * 13000 + nIndex]; // Still assuming N = 13000
Ensuite, vous pouvez y accéder comme suit:
// Assuming N = 13000, M = 4 std::vector<int> vec; vec.reserve(13000 * 4);
Merci beaucoup! Je pensais qu'il serait alloué dans un espace contigu après l'aplatissement si je le déclare comme vector
et réserve de l'espace à l'avance. Mais c'était une idée stupide de réfléchir à la signification du vecteur. :)