Quelqu'un a-t-il déjà utilisé stackalloc
lors de la programmation en C #? Je suis conscient de ce que fait, mais le seul moment où il apparaît dans mon code est par accident, car Intellisense le suggère lorsque je commence à taper static
, par exemple.
Bien que cela ne soit pas lié aux scénarios d'utilisation de stackalloc
, je fais en fait une quantité considérable d'interopérabilité héritée dans mes applications, donc de temps en temps, je pourrais recourir à l'utilisation de unsafe
code. Mais néanmoins, je trouve généralement des moyens d'éviter unsafe
complètement.
Et comme la taille de la pile pour un seul thread dans .Net est de ~ 1 Mo (corrigez-moi si je me trompe), je suis encore plus réservé stackalloc
.
Y a-t-il des cas pratiques où l'on pourrait dire: "c'est exactement la bonne quantité de données et de traitement pour que je devienne dangereux et que je les utilise stackalloc
"?
la source
System.Numbers
utilise beaucoup referencesource.microsoft.com/#mscorlib/system/...Réponses:
La seule raison à utiliser
stackalloc
est la performance (que ce soit pour les calculs ou l'interopérabilité). En utilisantstackalloc
au lieu d'un tableau alloué de tas, vous créez moins de pression GC (le GC doit moins fonctionner), vous n'avez pas besoin d'épingler les tableaux, il est plus rapide à allouer qu'un tableau de tas, et il est automatiquement libéré sur la méthode exit (les tableaux alloués au tas ne sont désalloués que lorsque GC s'exécute). De plus, en utilisant à lastackalloc
place d'un allocateur natif (comme malloc ou l'équivalent .Net), vous gagnez également en vitesse et en désallocation automatique à la sortie de la portée.En termes de performances, si vous utilisez,
stackalloc
vous augmentez considérablement les chances de succès du cache sur le processeur en raison de la localité des données.la source
J'ai utilisé stackalloc pour allouer des tampons pour le travail DSP en [quasi] temps réel. C'était un cas très particulier où les performances devaient être aussi cohérentes que possible. Notez qu'il y a une différence entre la cohérence et le débit global - dans ce cas, je n'étais pas préoccupé par le fait que les allocations de tas soient trop lentes, juste par le non déterminisme du ramasse-miettes à ce stade du programme. Je ne l'utiliserais pas dans 99% des cas.
la source
stackalloc
n'est pertinent que pour le code non sécurisé. Pour le code géré, vous ne pouvez pas décider où allouer les données. Les types de valeur sont alloués sur la pile par défaut (sauf s'ils font partie d'un type de référence, auquel cas ils sont alloués sur le tas). Les types de référence sont alloués sur le tas.La taille de pile par défaut pour une application .NET standard est de 1 Mo, mais vous pouvez la modifier dans l'en-tête PE. Si vous démarrez explicitement les threads, vous pouvez également définir une taille différente via la surcharge du constructeur. Pour les applications ASP.NET, la taille de pile par défaut n'est que de 256 Ko, ce qu'il faut garder à l'esprit si vous basculez entre les deux environnements.
la source
Initialisation Stackalloc des travées. Dans les versions précédentes de C #, le résultat de stackalloc ne pouvait être stocké que dans une variable locale de pointeur. Depuis C # 7.2, stackalloc peut désormais être utilisé dans le cadre d'une expression et peut cibler un span, et cela peut être fait sans utiliser le mot clé unsafe. Ainsi, au lieu d'écrire
Vous pouvez écrire simplement:
Ceci est également extrêmement utile dans les situations où vous avez besoin d'un peu d'espace de travail pour effectuer une opération, mais que vous voulez éviter d'allouer de la mémoire de tas pour des tailles relativement petites
Source: C # - Tout sur Span: Exploration d'un nouveau Mainstay .NET
la source
Span
n'est hélas pas disponible dans .NET Framework 4.7.2 et même pas dans 4.8 ... Donc cette nouvelle fonctionnalité de langage est encore d'une utilité limitée pour le moment.Il y a de bonnes réponses à cette question, mais je veux juste souligner que
Stackalloc peut également être utilisé pour appeler des API natives
De nombreuses fonctions natives nécessitent que l'appelant alloue un tampon pour obtenir le résultat renvoyé. Par exemple, la fonction CfGetPlaceholderInfo dans
cfapi.h
a la signature suivante.Pour l'appeler en C # via l'interopérabilité,
Vous pouvez utiliser stackalloc.
la source