L'analyse comparative de cette classe:
struct Sieve {
std::vector<bool> isPrime;
Sieve (int n = 1) {
isPrime.assign (n+1, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i <= (int)sqrt((double)n); ++i)
if (isPrime[i])
for (int j = i*i; j <= n; j += i)
isPrime[j] = false;
}
};
Je reçois plus de 3 fois plus de performances (temps CPU) avec 64-bit et 32-bit version (version release) lors de l'appel d'un constructeur pour un grand nombre, par ex.
Sieve s(100000000);
J'ai testé sizeof(bool)
et il est 1
pour les deux versions.
Quand j'ai substitut vector<bool>
avec vector<char>
de la performance devient le même pour 64-bits et 32-bits. Pourquoi est-ce?
Voici les temps d'exécution pour S(100000000)
(version 32 bits en mode premier, de 64 bits à la seconde)):
vector<bool>
0.97 s 3.12 s
vector<char>
0.99 s 0.99 s
vector<int>
1.57 s 1.59 s
J'ai aussi fait une folie test avec VS2010 (invité par Wouter Huysentruit de réponse), qui a produit 0.98 s 0.88 s. Si il ya quelque chose de mal avec VS2012 mise en œuvre.
J'ai soumis un rapport d'erreur à Microsoft Connect
MODIFIER
Beaucoup de réponses de commentaires ci-dessous sur les insuffisances de l'aide d' int
pour l'indexation. Cela peut être vrai, mais même le Grand Magicien lui-même est à l'aide d'une norme for (int i = 0; i < v.size(); ++i)
dans ses livres, donc, un tel modèle ne devrait pas subir une importante perte de performance. En outre, cette question a été soulevée au cours de Natifs de 2013 de la conférence et le président du groupe de C++ gourous ont fait part de leur début de recommandations d'utilisation size_t
pour l'indexation et un type de retour d' size()
comme une erreur. Ils ont dit: "nous sommes désolés, nous étions jeunes..."
Le titre de cette question pourrait être reformulée pour: Plus de 3 fois les performances de tomber sur ce code lors de la mise à niveau de VS2010 pour VS2012.
MODIFIER
J'ai fait une grossière tentative de se trouver un alignement de la mémoire d'index i
et j
et découvert que cette version instrumentée:
struct Sieve {
vector<bool> isPrime;
Sieve (int n = 1) {
isPrime.assign (n+1, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i <= sqrt((double)n); ++i) {
if (i == 17) cout << ((int)&i)%16 << endl;
if (isPrime[i])
for (int j = i*i; j <= n; j += i) {
if (j == 4) cout << ((int)&j)%16 << endl;
isPrime[j] = false;
}
}
}
};
l'auto-magiquement court vite maintenant (seulement 10% plus lente que la version 32 bits). Cette VS2010 et les performances du mal à accepter une théorie de l'optimiseur avoir des problèmes inhérents à traiter avec int
indices au lieu de size_t
.