2010-05-03 23 views
6

Si l'on pouvait placer un tableau de pointeurs sur les structures enfants dans des structures dangereuses en C# comme on le ferait en C, construire des structures de données complexes sans avoir un objet par nœud serait beaucoup plus facile et moins rapide. ainsi que syntaxiquement plus propre et beaucoup plus lisible.Quelle est la raison sous-jacente pour ne pas être en mesure de mettre des tableaux de pointeurs dans des structures dangereuses en C#?

Existe-t-il une raison architecturale profonde pour laquelle les tableaux fixes à l'intérieur de structures dangereuses ne peuvent être composés que de «types de valeur» et non de pointeurs? Je suppose que seuls les pointeurs explicitement nommés à l'intérieur des structs doivent être une décision délibérée d'affaiblir le langage, mais je ne trouve aucune documentation expliquant pourquoi c'est le cas, ou le raisonnement pour ne pas autoriser les tableaux de pointeurs dans les structures, car je supposerait que le ramasse-miettes ne devrait pas se préoccuper de ce qui se passe dans les structures marquées comme dangereuses. Digital Mars 'D gère élégamment les structures et les pointeurs en comparaison, et il me manque de ne pas pouvoir développer rapidement des structures de données succinctes; en faisant des références abstraites en C#, beaucoup de pouvoir semble avoir été retiré du langage, même si les pointeurs sont toujours là au moins dans un sens marketing. Peut-être que je me trompe à l'idée que les langues soient plus puissantes pour représenter efficacement des structures de données complexes au fil du temps.

Répondre

2

Je ne fais que deviner, mais cela peut avoir à faire avec différentes tailles de pointeurs pour différentes plates-formes cibles. Il semble que le compilateur C# utilise directement la taille des éléments pour les calculs d'index (c'est-à-dire qu'il n'y a pas de support CLR pour calculer les indices de tampons de taille fixe ...)

vous pouvez utiliser En tout cas un tableau de ulong s et jeter les pointeurs vers elle:

unsafe struct s1 
{ 
    public int a; 
    public int b; 
} 

unsafe struct s 
{ 
    public fixed ulong otherStruct[100]; 
} 

unsafe void f() { 
    var S = new s(); 
    var S1 = new s1(); 
    S.otherStruct[4] = (ulong)&S1; 
    var S2 = (s1*)S.otherStruct[4]; 
} 
4

Une raison très simple: dotNET a un compacteur garbage collector. Cela fait bouger les choses. Donc, même si vous pouviez créer des tableaux comme ça, vous auriez broche chaque bloc alloué et vous verriez le système ralentir à une analyse.

Mais vous essayez d'optimiser en fonction d'une hypothèse. L'allocation et le nettoyage des objets dans dotNET sont hautement optimisés. Écrivez donc d'abord un programme de travail, puis utilisez un profileur pour trouver vos goulots d'étranglement. Ce ne sera probablement pas l'allocation de vos objets.

Modifier, pour répondre à la dernière partie:

Peut-être que je me trompe d'attendre langues à devenir plus puissant à représenter structures de données complexes efficacement au fil du temps.

Je pense que C# (ou toute autre langue gérée) est beaucoup plus puissant à représenter structures de données complexes (efficace). En passant des pointeurs de bas niveau aux références récupérées. Mettre un tableau fixe de pointeurs dans une structure en ferait rapidement un mauvais candidat pour une struct.

+0

Qu'est-ce profileur recommandez-vous? – cons

+2

Cela ne peut pas être la raison, puisque vous pouvez très bien utiliser des pointeurs vers d'autres structures dangereuses dans des structures non sécurisées (il n'y a aucun problème pour créer une structure arborescente binaire ...) La restriction s'applique uniquement aux tableaux dans des structures non sécurisées tampons de taille), et la raison pour cela n'est pas évident à mon avis (Voir ma réponse pour une explication possible) – MartinStettner

+1

@cons: Voir cette question: http://stackoverflow.com/questions/3927/ –

1

La limite de taille recommandée pour une structure est de 16 octets. Par conséquent, sur un système x64, vous ne pouvez insérer que deux pointeurs dans le tableau, ce qui est inutile.

Vous devez utiliser des classes pour les structures de données complexes, si vous utilisez des structures, leur utilisation est très limitée. Vous ne pourriez pas, par exemple, créer une structure de données dans une méthode et la renvoyer, car elle contiendrait alors des pointeurs vers des structures qui n'existent plus puisqu'elles étaient allouées dans le cadre de la pile de la méthode.

+0

Intéressant. Pouvez-vous donner un lien vers certains articles, ou expliquer un peu pourquoi 16 octets? –

+0

@Alexander: C'est ce que Microsoft dit dans leurs directives: http://msdn.microsoft.com/en-us/library/y23b5415%28VS.71%29.aspx – Guffa

+0

Le seuil de taille où une classe deviendra plus efficace qu'un La structure varie considérablement avec les modèles d'utilisation. Les classes immuables de moins de 16 octets seront très rarement plus efficaces que les structures en dehors des scénarios inventés, mais avec de nombreux modèles d'utilisation, même de grandes structures (64-256 octets) peuvent surpasser les classes. Pour certains modèles d'utilisation, la «marge gagnante» pour les structures augmente en réalité avec des charges utiles plus importantes (à condition qu'elles ne soient pas trop importantes pour bloquer la pile). – supercat