L'initialisation d'un C++ d'un vecteur aléatoire à valeurs rapide...
Hey, id tiens à faire ce aussi vite que possible, car elle est appelée à BEAUCOUP de choses dans un programme, que je suis en train d'écrire, si il ya une façon plus rapide pour initialiser un C++ d'un vecteur aléatoire à valeurs que:
double range;//set to the range of a particular function i want to evaluate.
std::vector<double> x(30, 0.0);
for (int i=0;i<x.size();i++) {
x.at(i) = (rand()/(double)RAND_MAX)*range;
}
EDIT:Fixe x initialiseur.
Le type approprié pour l'accès à un vecteur de données de l'élément à l'indice est
Je suppose commune compilateurs déplacer le
Curieux de savoir si un profil a effectivement identifié ce problème.
std::vector<...>::size_type
, pas int
.Je suppose commune compilateurs déplacer le
range/RAND_MAX
hors de la boucle eux-mêmes dans leur optimiseurs?Curieux de savoir si un profil a effectivement identifié ce problème.
OriginalL'auteur Flamewires | 2010-05-18
Vous devez vous connecter pour publier un commentaire.
aujourd'hui, ce devrait être vraiment rapide étant donné que la boucle ne sera pas exécuté.Personnellement, je serais probablement utiliser quelque chose comme ceci:
Edit: C'est purement une micro-optimisation qui pourrait faire aucune différence, mais vous pourriez envisager de réorganiser le calcul pour obtenir quelque chose comme:
Bien sûr, il ya une très bonne chance que le compilateur va déjà le faire (ou quelque chose d'équivalent), mais il ne fera pas de mal à essayer quand même (même si c'est vraiment susceptible d'aider à l'optimisation éteint).
Edit2: "sbi" (comme c'est généralement le cas) est la droite: vous pourriez gagner un peu en réservant de l'espace, puis à l'aide d'un itérateur d'insertion pour mettre les données en place:
Comme avant, nous sommes dans une telle microscopique de l'optimisation, je ne suis pas sûr que je serais vraiment attendre pour voir une différence. En particulier, puisque c'est fait avec des modèles, il ya une très bonne chance que la plupart (si pas tous), le code sera généré en ligne. Dans ce cas, l'optimiseur de requête est susceptible d'avis que les données initiales de tous est écrasée, puis passez à l'initialisation.
En fin de compte, cependant, presque la seule partie qui est vraiment probablement de faire une différence importante est de se débarrasser de la
.at(i)
. Les autres pourrait, mais avec les optimisations activées, je ne serais pas vraiment attendre d'eux.Encore pré-initialise le vecteur avec
0.0
valeurs qui sont ensuite remplacées. N'est-ce pasreserve()
et et insérez itérateur éliminer?ça doit être une première, avec mon (pauvre) de frappe, c'est souvent l'inverse! 🙂
Jerry, j'ai formulé ce que j'ai dit comme une question, parce que je ne suis pas sûr. Je peux imaginer la charge supplémentaire d'un itérateur d'insertion prend plus de temps que la première initialisation de quelques built-ins, surtout si pas tous de l'ancien peut être insérée et le dernier est optimisé pour une
std::memset()
, mis en œuvre comme un PROCESSEUR intrinsèque. Je suppose que dans la fin, vous avez juste à mesurer. Mais, à moins que l'application consacre 20% de son temps dans cette boucle, personne ne va à l'avis de toute façon, même si l'on double la vitesse.Merci, j'ai édité pour corriger ces problèmes.
OriginalL'auteur Jerry Coffin
J'ai été à l'aide de Jerry Cercueil du foncteur méthode depuis un certain temps, mais avec l'arrivée de C++11, nous avons des charges de frais nouveau nombre aléatoire de la fonctionnalité. Pour remplir un tableau aléatoire
float
valeurs, nous pouvons maintenant faire quelque chose comme ce qui suit . . .Voir la section pertinente de Wikipedia pour plus de moteurs et de distributions
OriginalL'auteur learnvst
Oui, alors que x.à(i) la vérification des limites, x[i] ne pas le faire.
Aussi, votre code est incorrect, car vous avez omis de spécifier la taille de x à l'avance. Vous avez besoin d'utiliserstd::vector<double> x(n)
, où n est le nombre d'éléments que vous souhaitez utiliser; sinon, votre boucle, il n'y aura jamais exécuter.Alternativement, vous pouvez personnaliser un itérateur pour générer des valeurs aléatoires et de le remplir à l'aide de l'itérateur; parce que le std::vector constructeur permet d'initialiser l'un de ses éléments, de toute façon, donc si vous avez une coutume classe iterator qui génère des nombres aléatoires, vous pouvez être en mesure d'éliminer une passe sur les éléments.
En termes de mise en œuvre d'un itérateur de votre propre, voici mon code non testé:
Avec le code ci-dessus, il devrait être possible d'utiliser:
Cela dit, la génération de code pour l'autre solution est plus simple, et franchement, je me permets juste de remplir de façon explicite le vecteur sans avoir recours à quelque chose de compliqué comme ça.... mais c'est cool de penser.
Oh, désolé, je viens d'écrire ici, c'est plus pour le concept, mais je vais corriger ça, ty. Pourriez-vous me donner un exemple ou m'indiquer où je peux lire sur mon itérateur? Je suis assez novice en C++. Merci
ouais... vous devez créer une classe qui est conforme à l'un des concepts d'itérateur. Voir: sgi.com/tech/stl/Iterators.html . Si vous êtes assez nouveau pour C++, puis la création de votre propre itérateur peut-être pas une bonne idée, pour le moment, car il implique des notions telles que les "traits de type", "modèles", "modèle de spécialisation", les "concepts", et "la surcharge d'opérateur". Si vous êtes familier avec ces, alors il peut être une chose raisonnable à faire.
IMO, c'est une assez mauvaise idée, en tout cas. Alors que c'est possible à penser de la génération de (pseudo-)aléatoire de numéros que de parcourir une séquence, je pense qu'il est plus susceptible d'induire en erreur que de bien.
Je ne sais pas. Tel un itérateur ne semble pas du tout loin une étape de l'aide de l'entrée des itérateurs sur
/dev/random
, qui est bien connu et établi icône de C++ (qui échoue uniquement dans ce cas, car la lecture de/dev/random
n'atteint jamais EOF).OriginalL'auteur Michael Aaron Safyan
опоздал 🙁
OriginalL'auteur niXman
Vous pouvez envisager d'utiliser un générateur de nombres pseudo aléatoires qui donne en sortie une séquence. Depuis plus PRNGs, il suffit de fournir une séquence de toute façon, ce sera beaucoup plus efficace que de simplement appeler rand() maintes et maintes fois.
Mais ensuite, je pense que j'ai vraiment besoin d'en savoir plus sur votre situation.
OriginalL'auteur Tom
@Jerry Cercueil de réponse est très bon. Deux autres pensées, si:
Inline - Tous de votre vecteur d'accès est très rapide, mais si l'appel à rand() est hors-ligne, l'appel de la fonction de surcharge pourrait dominer. Si c'est le cas, vous devrez peut-être rouler vos propres générateur de nombres pseudo-aléatoires.
SIMD - Si vous allez rouler votre propre GÉNÉRATEUR, vous pourriez faire ainsi calculer 2 doubles (ou 4 chars) à la fois. Cela permettra de réduire le nombre de l'int qui flottent des conversions ainsi que les multiplications. Je n'ai jamais essayé, mais apparemment, il ya un SIMD version de la Mersenne Twister c'est très bon. Un simple générateur linéaire à congruence peut-être assez bon aussi (et c'est probablement ce que rand() utilise déjà).
OriginalL'auteur celion
Vous devez inclure vecteur, l'algorithme, le temps, cstdlib.
OriginalL'auteur Taras Shevchenko
La façon dont je pense à propos de ces est un caoutchouc rencontre la route approche.
En d'autres termes, il y a un nombre minimum les choses qui doivent arriver, sans se déplacer, telles que:
la
rand()
fonction doit être appelée à N fois.le résultat de
rand()
doit être converti en double, puis multiplié par quelque chose.l'résultant numéros doivent obtenir stockés dans consécutives éléments d'un tableau.
L'objet est, au minimum, pour obtenir ces choses.
D'autres préoccupations, comme si ou de ne pas utiliser un
std::vector
et les itérateurs sont très bien aussi longtemps qu'ils n'ont pas de place supplémentaire cycles.La meilleure façon de voir si ils ajoutent supplémentaire importante des cycles est la seule étape avec le code lors de l'assemblée niveau de langue.
OriginalL'auteur Mike Dunlavey