Quand sont les structures de la réponse?

Je suis en train de faire un raytracer projet de loisirs, et à l'origine j'ai été en utilisant les structures pour mon Vecteur et Ray objets, et j'ai pensé à un raytracer est la situation parfaite pour les utiliser: vous créer des millions d'entre eux, ils ne vivent pas plus longtemps que d'une seule méthode, ils sont légers. Cependant, en changeant simplement 'struct' à 'classe' sur le Vecteur et Ray, j'ai eu un gain de performance significatif.

Ce qui donne? Ils sont tous les deux petits (3 flotteurs pour les Vecteurs 2 Vecteurs pour les Rayons), de ne pas avoir copié autour de trop. Je ne les transmettre à des méthodes si nécessaire bien sûr, mais c'est inévitable. Alors, quelles sont les erreurs les plus communes que tuer des performances lors de l'utilisation de structures? J'ai lu cette article MSDN qui dit la chose suivante:

Lorsque vous exécutez cet exemple, vous verrez que la structure de la boucle est un ordre de grandeur plus rapide. Cependant, il est important de se méfier de l'utilisation de ValueTypes lorsque vous les traiter comme des objets. Cela ajoute plus de boxing et unboxing surcharge de votre programme, et peut finir par vous coûter plus que ce qu'il aurait fait si vous aviez coincé avec des objets! Pour le voir en action, modifiez le code ci-dessus pour utiliser un tableau de foos et des bars. Vous verrez que la performance est plus ou moins égale.

Il est cependant assez ancien (2001) et de l'ensemble "les mettre dans un tableau les causes boxing/unboxing" m'a frappé comme étrange. Est-ce vrai? Cependant, je n'ai pré-calculer la primaire de rayons et de les mettre dans un tableau, j'ai pris sur cet article et calculé la primaire ray quand j'en avais besoin et jamais ajouté à un tableau, mais ça n'a rien changé: les classes, il était encore 1,5 x plus rapide.

Je suis en cours d'exécution .NET 3.5 SP1 qui, je crois, correction d'un problème où struct méthodes n'étaient pas toujours en-alignés, donc ça ne peut pas être non plus.

Donc en gros: des conseils, des choses à considérer et comment l'éviter?

EDIT: Comme l'a suggéré dans certaines réponses, j'ai mis en place un projet de test où j'ai essayé en passant des structures comme la réf. Les méthodes pour l'ajout de deux Vecteurs:

public static VectorStruct Add(VectorStruct v1, VectorStruct v2)
{
  return new VectorStruct(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z);
}

public static VectorStruct Add(ref VectorStruct v1, ref VectorStruct v2)
{
  return new VectorStruct(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z);
}

public static void Add(ref VectorStruct v1, ref VectorStruct v2, out VectorStruct v3)
{
  v3 = new VectorStruct(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z);
}

Pour chaque j'ai eu une variation de la suite de méthode de référence:

VectorStruct StructTest()
{
  Stopwatch sw = new Stopwatch();
  sw.Start();
  var v2 = new VectorStruct(0, 0, 0);
  for (int i = 0; i < 100000000; i++)
  {
    var v0 = new VectorStruct(i, i, i);
    var v1 = new VectorStruct(i, i, i);
    v2 = VectorStruct.Add(ref v0, ref v1);
  }
  sw.Stop();
  Console.WriteLine(sw.Elapsed.ToString());
  return v2; //To make sure v2 doesn't get optimized away because it's unused. 
}

Tous semblent effectuer à peu près identiques. Est-il possible qu'ils soient optimisés par le JIT à ce qui est le meilleur moyen de passer cette structure?

EDIT2: je dois notons au passage que l'utilisation de structures dans mon projet de test est environ 50% plus rapide que l'utilisation d'une classe. Pourquoi est-ce différent pour mon raytracer je ne sais pas.

  • Bonne chance avec le projet, d'un lancer de rayons est quelque chose que je vais attaquer bientôt.
  • Voir aussi stackoverflow.com/questions/521298/when-to-use-struct-in-c/... (surtout ma réponse là 🙂 )
  • La création d'un raytracer est un beaucoup de plaisir. Je trouve cela fascinant, vous pouvez créer une image à partir de rien de plus qu'un tas de chars et relativement simple vecteur de mathématiques.
  • Je ne pense pas que l'article dit que le fait de mettre les structures dans un tableau des causes de la boxe. Elle a averti que l'utilisation dans des endroits où les objets sont attendus cause de boxe; par exemple, si vous passez à une méthode attend un argument de type object.
  • double possible de Quand utiliser struct en C#?
InformationsquelleAutor JulianR | 2009-02-28