Si k = -1 (int) et n = 2 (int), alors static_cast< unsigned int >(-1) est égal à 232 - 1 et static_cast< unsigned int >(2) est égal à 2. La comparaison renvoie donc bien false comme on le souhaite. Le bound checking se fait donc parfaitement avec des entiers signés en une seule opération. Pour se convaincre que le cout est le même, il suffit de regarder l'assembleur de :
bool in_range(int k, int n) {
return static_cast<unsigned int>(k) < static_cast<unsigned int>(n);
}; et de
bool in_range(unsigned int k, unsigned int n) {
return k < n;
}; Ce sont exactement les mêmes (testé avec clang++).
De toute façon, le problème du bound-checking sur chaque élément n'est pas vraiment une histoire de une où deux comparaisons. Sa présence empêche la vectorisation automatique et bien d'autres optimisations. Il est donc impossible d'avoir un bound-checking en C++ sans perte de performance notable. Le seul moyen pour avoir un bound-checking raisonnable est que les tableaux fassent partie du langage comme en Fortran, C# ou Rust. Il faut ensuite mettre tout cela dans le compilateur ce qui ne doit pas être une mince affaire. Je crois par exemple que l'équivalent C# de
for (int k = 0; k < n; ++k) {
v[k] = ;
}
vérifie une fois avant d'entrer dans la boucle que n <= v.size() et ne fait plus aucun bound-cheking ensuite. On peut alors dire que le bound-cheking a un impact négligeable sur la performance. Mais, je ne crois pas que ces idées soient poussées très loin.
Enfin, pour remettre une couche sur les itérateurs, on fait comment une recherche dichotomique dans un tableau trié avec des itérateurs ? ;-)
[^] # Re: Une chose que j'ai oublié d'ajouter
Posté par InsideLoop . En réponse à la dépêche Le langage Rust en version 1.0 alpha, on arrête de tout casser !. Évalué à 1. Dernière modification le 03 février 2015 à 14:59.
Si k = -1 (int) et n = 2 (int), alors static_cast< unsigned int >(-1) est égal à 232 - 1 et static_cast< unsigned int >(2) est égal à 2. La comparaison renvoie donc bien false comme on le souhaite. Le bound checking se fait donc parfaitement avec des entiers signés en une seule opération. Pour se convaincre que le cout est le même, il suffit de regarder l'assembleur de :
et debool in_range(int k, int n) {
return static_cast<unsigned int>(k) < static_cast<unsigned int>(n);
};
Ce sont exactement les mêmes (testé avec clang++).bool in_range(unsigned int k, unsigned int n) {
return k < n;
};
De toute façon, le problème du bound-checking sur chaque élément n'est pas vraiment une histoire de une où deux comparaisons. Sa présence empêche la vectorisation automatique et bien d'autres optimisations. Il est donc impossible d'avoir un bound-checking en C++ sans perte de performance notable. Le seul moyen pour avoir un bound-checking raisonnable est que les tableaux fassent partie du langage comme en Fortran, C# ou Rust. Il faut ensuite mettre tout cela dans le compilateur ce qui ne doit pas être une mince affaire. Je crois par exemple que l'équivalent C# de
vérifie une fois avant d'entrer dans la boucle que n <= v.size() et ne fait plus aucun bound-cheking ensuite. On peut alors dire que le bound-cheking a un impact négligeable sur la performance. Mais, je ne crois pas que ces idées soient poussées très loin.
Enfin, pour remettre une couche sur les itérateurs, on fait comment une recherche dichotomique dans un tableau trié avec des itérateurs ? ;-)