Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
Community & Social
Windows Tipps & SecurityBeta-Update: Diese Funktionen testet Microsoft für Windows 11 v25H2(02.10.2026 um 21:16 Uhr)
••
IT Security NachrichtenTrickreicher Angriff knackt RSA-Signaturen – ein bisschen(02.10.2026 um 21:22 Uhr)
•
IT NachrichtenMicrosoft adds support for Linux containers in WSL(02.10.2026 um 09:25 Uhr)
•••••
IT NachrichtenApple sounds the alarm on AI agents and 'Full Disk Access'(02.10.2026 um 21:22 Uhr)
••
Windows Tipps & SecurityBeta-Update: Diese Funktionen testet Microsoft für Windows 11 v25H2(02.10.2026 um 21:16 Uhr)
••
IT Security NachrichtenTrickreicher Angriff knackt RSA-Signaturen – ein bisschen(02.10.2026 um 21:22 Uhr)
•
IT NachrichtenMicrosoft adds support for Linux containers in WSL(02.10.2026 um 09:25 Uhr)
•••••
IT NachrichtenApple sounds the alarm on AI agents and 'Full Disk Access'(02.10.2026 um 21:22 Uhr)
••
Intelligence View
⚡ tsecurity.de Intelligence

Performance: Structs e Cópias (Defensivas)

Olá! Este é mais um post da seção Performance e vamos falar sobre uma armadilha invisível no uso de structs em C#: as cópias defensivas. Vamos lá! Structs: Por …

Beitrag
0
Seite
0
↗ Quelle (dev.to)
Social ReaktionenReagiere als Erste:r — dein Feedback zählt!

Olá!



Este é mais um post da seção Performance e vamos falar sobre uma armadilha invisível no uso de structs em C#: as cópias defensivas.



Vamos lá!






Structs: Por quê?



Vamos recapitular: structs são uma escolha excelente para em cenários onde alocação de memória é uma questão crítica. Por existirem apenas na stack, tendo portanto uma existência efêmera e não sujeita à ação do Garbage Collector, seu uso afeta positivamente o desempenho de uma aplicação, efeito que pode ser constatado no caminho crítico da mesma via profile, ou via benchmarks em ambiente de desenvolvimento, quando avaliado diante de classes.






Mas nem tudo são flores!



Ainda que sejam uma alternativa ao uso de classes e tenham por principal característica a evitação da alocação de memória no heap, existe uma armadilha oculta: as cópias (defensivas).






Cópias: o fundamental



Quando uma struct é passada como parâmetro para um método, dada sua natureza de value type, a passagem acontece por valor, ou seja, uma cópia da struct em questão é gerada dentro do método, o que impede naturalmente que a struct original seja modificada, já que a cópia não é um ponteiro pra ela e encerra seu ciclo de vida ao final do método no qual foi recebida.






O Modificador in



Para permitir a passagem de structs como parâmetros por referência, surgiu o modificador in, o que impede que uma cópia da struct seja criada mas que, ao mesmo tempo, cria um risco: mudança implícita de estado.



Por ser passada por referência, qualquer alteração no estado interno da struct perdurará para além do método invocado, tornando a instância da struct vulnerável à mudanças indesejadas, ainda que o modificador in crie um contexto readonly que não permita a alteração explícita do estado da struct.






Cópias defensivas, uma (aparente) solução



Cópias defensivas são uma forma do compilador (Roslyn) evitar que sua struct sofra mudanças indesejadas quando passadas como parâmetros in, o que aumenta a segurança da aplicação contra efeitos colaterais. Mas, como bem sabemos, segurança sempre custará performance e é exatamente o que acontece neste caso.






Um pequeno exemplo



Aqui temos uma struct chamada Square que representa um quadrado. Um quadrado tem quatro lados iguais, portanto apenas o tamanho de um lado precisa ser conhecido. Vejamos:




public struct Square
{
public double Side { get; init; }

public double Area => Side * Side;
}






Repare que esta struct é imutável, ou seja, suas propriedades não podem ser modificadas durante um dado processamento. O problema é que o compilador não sabe se há alguma mudança de estado acionada quando a propriedade Area é invocada e, por isso, cria uma cópia defensiva sempre que encontra uma invocação a este método.




Span<Square> squares = stackalloc Point[1_000];
for(int i = 0, i < squares.Lenght; i++)
{
squares[i] = new Square { Side = i };
}

var panel = new Panel();
panel.Render(squares); //Renderiza os quadrados via propriedade `Area`.






Adivinhe o que acontece aqui? Se você respondeu que mil cópias defensivas serão criadas a partir do array de Point, acertou na mosca!



Mas, William, mil cópias?!



Aqui está o pulo do gato: cada vez que uma propriedade é utilizada, o compilador cria uma cópia da sua struct toda pra garantir que aquela propriedade não afetará seu estado interno. Percebe o impacto potencial que estas operações geram sobre a performance?






Readonly ao resgate!



Felizmente existe uma forma de lidar com esse problema sem prejuízo da performance, o modificador readonly. Este modificador indica ao compilador que sua struct é imutável, o que garante que não haverá mudança de estado quando a struct for manipulada por um dado método.



O modificador readonly pode ser aplicado em duas dimensões: a struct inteira ou em certas propriedades. Vejamos:




public readonly struct Square
{
public double Side { get; init; }

public double Area => Side * Side;
}






Com o modificador aplicado à struct toda, o compilador entender que não há a possibilidade de mudança de estado quando a instância tiver suas propriedades invocadas. Isso faz com que nenhuma cópia defensiva seja criada.




public struct Square
{
public readonly double Side { get; init; }

public double Area => Side * Side
}






Com o modificador aplicado apenas a Side o compilador entenderá que a propriedade Area oferece o risco de mudança no estado interno, o que implicará uma cópia defensiva. Entretanto, o mesmo não acontecerá com a propriedade Side.






Performance: medindo o impacto



Abaixo temos uma demonstração do prejuízo à performance por força das cópias defensivas. Vejamos:



Benchmark



Aqui fica claro que, com structs grandes no caminho crítico da aplicação, sem o devido cuidado, as cópias defensivas oferecem um prejuízo perceptível, dado que o mesmo é mensurável em benchmark com dados fictícios.






Conclusão



Conhecer as características internas do compilador é muito útil para pensar sobre como desenhar suas structs e utilizá-las. Este é um caso onde seria simplesmente impossível considerar que suas structs são a causa do problema sem esse conhecimento.



Como sempre, o código do benchmark está disponível no GitHub para te permitir testar e modificar à vontade.



Gostou? Me deixe saber pelo indicadores. Caso tenha alguma dúvida, deixe um comentário ou me procure nas redes sociais. Será um prazer te responder.



Muito obrigado por ler até aqui, e até a próxima!

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Performance: Structs e Cópias (Defensivas)

Thematisch verwandte Begriffe: Performance, Structs, Cópias, Defensivas · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag