Alguém já usou stackalloc
na programação em C #? Estou ciente do que faz, mas a única vez que aparece no meu código é por acidente, porque o Intellisense sugere isso quando começo a digitar static
, por exemplo.
Embora não esteja relacionado aos cenários de uso stackalloc
, na verdade, eu faço uma quantidade considerável de interoperabilidade herdada em meus aplicativos, para que de vez em quando eu pudesse recorrer ao uso de unsafe
código. Mas, no entanto, costumo encontrar maneiras de evitar unsafe
completamente.
E como o tamanho da pilha de um único thread no .Net é de ~ 1Mb (me corrija se estiver errado), sou ainda mais reservado stackalloc
.
Existem casos práticos em que se pode dizer: "essa é exatamente a quantidade certa de dados e processamento para eu ficar insegura e usar stackalloc
"?
fonte
System.Numbers
usa muito referencesource.microsoft.com/#mscorlib/system/...Respostas:
O único motivo para usar
stackalloc
é o desempenho (para cálculos ou interoperabilidade). Ao usar emstackalloc
vez de uma matriz alocada ao heap, você cria menos pressão do GC (o GC precisa executar menos), não é necessário fixar as matrizes, é mais rápido alocar do que uma matriz de heap e é automaticamente liberado no método exit (matrizes de heap alocadas somente são desalocadas quando o GC é executado). Além disso, aostackalloc
invés de usar um alocador nativo (como malloc ou o equivalente .Net), você também ganha velocidade e desalocação automática na saída do escopo.Em termos de desempenho, se você usar
stackalloc
, aumenta bastante a chance de acertos de cache na CPU devido à localidade dos dados.fonte
Eu usei o stackalloc para alocar buffers para o trabalho DSP [quase] em tempo real. Foi um caso muito específico em que o desempenho precisava ser o mais consistente possível. Observe que há uma diferença entre consistência e taxa de transferência geral - nesse caso, eu não estava preocupado com as alocações de heap sendo muito lentas, apenas com o não determinismo da coleta de lixo naquele ponto do programa. Eu não o usaria em 99% dos casos.
fonte
stackalloc
é relevante apenas para código não seguro. Para código gerenciado, você não pode decidir onde alocar dados. Os tipos de valor são alocados na pilha por padrão (a menos que façam parte de um tipo de referência; nesse caso, eles são alocados no heap). Os tipos de referência são alocados no heap.O tamanho da pilha padrão para um aplicativo .NET simples baunilha é de 1 MB, mas você pode alterar isso no cabeçalho do PE. Se você estiver iniciando threads explicitamente, também poderá definir um tamanho diferente através da sobrecarga do construtor. Para aplicativos ASP.NET, o tamanho da pilha padrão é de apenas 256K, o que deve ser lembrado se você alternar entre os dois ambientes.
fonte
Inicialização Stackalloc de vãos. Nas versões anteriores do C #, o resultado do stackalloc só podia ser armazenado em uma variável local do ponteiro. A partir do C # 7.2, o stackalloc agora pode ser usado como parte de uma expressão e pode ser direcionado a uma extensão, e isso pode ser feito sem o uso da palavra-chave não segura. Assim, em vez de escrever
Você pode escrever simplesmente:
Isso também é extremamente útil em situações em que você precisa de algum espaço temporário para executar uma operação, mas deseja evitar a alocação de memória heap para tamanhos relativamente pequenos
Fonte: C # - Tudo sobre o Span: explorando uma nova base do .NET
fonte
Span
infelizmente não está disponível no .NET framework 4.7.2 e nem mesmo no 4.8 ... Portanto, o novo recurso de idioma ainda é de uso limitado no momento.Existem ótimas respostas nesta pergunta, mas eu só quero ressaltar que
Stackalloc também pode ser usado para chamar APIs nativas
Muitas funções nativas exigem que o chamador aloque um buffer para obter o resultado do retorno. Por exemplo, a função CfGetPlaceholderInfo
cfapi.h
possui a seguinte assinatura.Para chamá-lo em C # por meio de interoperabilidade,
Você pode fazer uso do stackalloc.
fonte