Pergunta

Quando você precisa ter muito pequenos objetos, digamos que contém 2 propriedade float, e você terá que milhões deles que não estão indo ser "destruído" de imediato, são estruturas uma escolha melhor ou aulas?

Como em XNA como uma biblioteca, há point3s, etc, como estruturas, mas se você precisar se agarrar esses valores por um longo tempo, seria uma ameaça performance?

Foi útil?

Solução

Ao contrário da maioria das perguntas sobre estruturas, isso realmente parece ser um bom uso de um struct. Se os dados que ele contém são tipos de valor, e você está indo para usar um monte deles, uma estrutura que funciona bem.

Algumas dicas:

:: A estrutura não deve ser maior do que 16 bytes, ou você perde as vantagens de desempenho.

:: Faça o imutável struct. Isso torna o uso mais claro.

Exemplo:

public struct Point3D {

   public float X { get; private set; }
   public float Y { get; private set; }
   public float Z { get; private set; }

   public Point3D(float x, float y, float z) {
      X = x;
      Y = y;
      Z = z;
   }

   public Point3D Invert() {
      return new Point3D(-X, -Y, -Z);
   }

}

Outras dicas

A resposta depende de onde os objetos / valores eventualmente será armazenado. Se eles devem ser armazenados em uma coleção não tipificada como ArrayList, então você acaba de boxe eles. Boxe cria um objeto wrapper para um struct ea pegada é o mesmo que com um objeto de classe. Por outro lado, se você usar uma matriz tipificada como T [] ou List, em seguida, usando estruturas só irá armazenar os dados reais para cada elemento com pegada para coleção inteira e não apenas os seus elementos.

Assim estruturas são mais eficientes para uso em T [] arrays.

A grande preocupação é se a memória é alocada na pilha ou a pilha. Structs ir na pilha por padrão, ea pilha é geralmente muito mais limitados em termos de espaço. Assim, a criação de um monte de estruturas apenas como aquele pode ser um problema.

Na prática, no entanto, eu realmente não acho que é tão grande de um negócio. Se você tiver que muitos deles fazem parte provável de uma instância de classe (na pilha) em algum lugar.

Struct parece certo para esta aplicação.

Tenha em mente que a "necessidade de agarrar esses valores" implica o seu armazenamento no lugar montão, provavelmente um campo de matriz de uma instância de classe.

Uma coisa a observar é que isso resulta em uma alocação de heap de objeto grande. Não é que claro como, se em tudo, este montão defrags si, no entanto por longos viveu objetos que talvez não seja um problema.

Usando classe para milhões desses tipos de dados provavelmente seria caro no volume da tesoura de dereferencing que provavelmente vai ter lugar para as operações sobre este tipo.

Como regra geral, grandes conjuntos de dados não-alias (ou seja, não compartilhada) do mesmo tipo é melhor armazenados em estruturas de desempenho desde que você reduzir o número de indireções. (Veja também quando-é-estruturas-the-resposta ). A diferença de desempenho exata entre classe e struct depende do seu uso. (Por exemplo, em operações, não é apenas peças de acesso do struct? Você faz um monte de cópia temporária? Se a estrutura é pequena provavelmente é sempre melhor para uso, mas se é grande, criando cópias temporárias podem atrasá-lo. Se você torná-lo imutável você terá que sempre copiar a coisa toda para alterar o valor.)

Em caso de dúvida, medida.

Uma vez que você está interessado em possíveis efeitos a longo prazo que podem não ser aparente por tal medida, estar ciente de que essas matrizes são provavelmente armazenados na pilha de grande objeto e deve ser, em vez de destruídos e re-alocados reutilizado . (Veja CRL Inside Out: Large Object Heap Uncovered .)

Ao passar estruturas de maior porte em chamadas que você pode querer passá-los com o argumento ref à cópia evitar.

Tipos de valor (struct) são bons para o tipo que não são atribuídos no montão muitas vezes, isto é, na sua maioria são contidos em outra referência ou valor de tipo.

O exemplo Vector3 lhe deu é um exemplo perfeito. Você raramente vai ter pendurado Vector3 na pilha, eles vão na maioria das vezes ser contida em um tipo que em si é na pilha, ou usado como uma variável local, caso em que, será alocada na pilha.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top