En el .NET struct design guidelines, da el tamaño máximo sensible de una estructura a 16 bytes. ¿Cómo se determina qué tan grande es su estructura y se ve afectada por la arquitectura en la que se ejecuta su programa? ¿Este valor es solo de 32 bits o para ambos archs?Tamaños de estructuras en 32 bit y 64 bit
Respuesta
Sí, el tamaño de una estructura se ve afectado por la arquitectura. Las estructuras de C# en 32 bits están alineadas en límites de 4 bytes, y en 64 bits están alineadas en 8 bytes.
Ejemplo:
struct Foo
{
int bar;
}
instancias de esta struct tomarán 4 bytes en los procesos de 32 bits, y 8 bytes en los procesos de 64 bits, a pesar de la "barra int" toma sólo 4 bytes de ambos procesos 32 y 64 bits .
Actualización:
lo hice algunas pruebas con esto.Escribí este código:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication3
{
struct Bar
{
int a;
}
struct Foo
{
Uri uri;
int a;
}
class Program
{
static void Main(string[] args)
{
Foo[] foo;
long fooBefore = System.GC.GetTotalMemory(true);
foo = new Foo[10];
long fooAfter = System.GC.GetTotalMemory(true);
Bar[] bar;
long barBefore = System.GC.GetTotalMemory(true);
bar = new Bar[10];
long barAfter = System.GC.GetTotalMemory(true);
Foo aFoo = new Foo();
Bar aBar = new Bar();
System.Console.Out.WriteLine(String.Format("[Foo] Size of array of 10: {0}, Marshal size of one: {1}", fooAfter - fooBefore, System.Runtime.InteropServices.Marshal.SizeOf(aFoo)));
System.Console.Out.WriteLine(String.Format("[Bar] Size of array of 10: {0}, Marshal size of one: {1}", barAfter - barBefore, System.Runtime.InteropServices.Marshal.SizeOf(aBar)));
System.Console.ReadKey();
}
}
}
Como un proceso de 64 bits, consigo esta salida:
[Foo] Size of array of 10: 208, Marshal size of one: 16
[Bar] Size of array of 10: 88, Marshal size of one: 4
Como un proceso de 32 bits, consigo esta salida:
[Foo] Size of array of 10: 92, Marshal size of one: 8
[Bar] Size of array of 10: 64, Marshal size of one: 4
Observaciones:
- La estructura simple, Bar, parece tomar 4 bytes en ambos 32 bits y los procesos de 64 bits
- La otra estructura, Foo, parece tomar 8 bytes en 32 bits (4 bytes para el int y 4 bytes para la referencia al Uri), pero 16 bytes en 64 bits (4 bytes para el int, 8 bytes para la referencia al Uri, y creo que 4 bytes para la alineación)
No es un valor difícil: es solo una guía, una regla de oro. Dependiendo de la situación exacta, 24 o incluso 32 bytes podrían ser perfectamente justificables, pero si su estructura es tan grande, realmente debería preguntarse si es apropiado como estructura en primer lugar. Puede ser - en cuyo caso tomar la decisión de copiar esos 32 bytes en cualquier momento en que realice una tarea o pase un argumento en un método (etc.) puede ser lo correcto; en otros casos, realmente deberías estar usando una clase.
En cuanto a cómo determina qué tan grande es su estructura, por lo general es bastante obvio, ya que normalmente un tipo de valor solo contiene otros tipos de valores. Si su estructura contiene referencias (o un IntPtr
/UIntPtr
), eso es más un problema, pero eso es bastante raro. (Como señala Mehrdad, también está el problema del relleno por el bien de la alineación).
Por otra parte, me resulta extremadamente raro que quiera escribir mi propia estructura de todos modos. ¿Cuál es tu situación?
En .Net la mayoría de los tipos no cambian de tamaño entre un programa de 32 y 64 bits. Los únicos 2 tipos de valores definidos por el marco que va a cambiar su tamaño basado en la plataforma son
- IntPtr
- UIntPtr
A menos que tenga uno de éstos directa o indirectamente, en su estructura, se no debería cambiar el tamaño entre las plataformas.
Como Mehrdad señaló, las otras dos clases de campos que cambiarán de tamaño basadas en la plataforma son
- Punteros
- Tipos de referencia
todos estos tipos, aunque va a cambiar en el exactamente de la misma manera. 4 bytes en una plataforma de 32 bits y 8 bytes en una plataforma de 64 bits.
- 1. .net Utilidad InstallUtil - 32 bit vs 64 bit
- 2. Convertir 32 bit dll a 64 bit dll
- 3. .net console app 32 vs 64 bit
- 4. CGFloat: redondo, piso, abs y precisión de 32/64 bit
- 5. Python: aritmética bit a bit sin signo de 32 bit
- 6. Oracle Install para conectividad SSIS (y controladores 32 64 bit)
- 7. Ejecutando código de ensamblado de 32 bits en un procesador Linux y 64 bit de 64 bit: explique la anomalía
- 8. Java performance 64 bit
- 9. SWT en Windows 64-bit
- 10. 64 bit enum en C++?
- 11. dll de 32 bits en Office 64 bit
- 12. ¿Por qué es esto más rápido en 64 bit que en 32 bit?
- 13. Java 64 bit Pregunta JDK
- 14. Identificación de la máquina de destino (32 bit o 64 bit) con implementación ClickOnce
- 15. Compilar ASP.NET a 64 BIT
- 16. Cuándo usar Eclipse 64 bit
- 17. ¿Cómo obtengo libpam.so.0 (32 bit) en mi 64 bit RHEL6?
- 18. Cambios usando Winspool.drv en Windows 7 64 bit desde Windows XP 32 bit
- 19. manera portátil de lidiar con 64/32 bit time_t
- 20. Diferentes referencias de ensamblado .NET según 32-64 bit
- 21. Error del ensamblador: Mach-O 64 bit no admite direcciones absolutas de 32 bit
- 22. Comprensión del tamaño de objeto CLR entre 32 bit frente a 64 bit
- 23. Agregando soporte de 64 bit al código existente de 32 bit, ¿es difícil?
- 24. ¿Cómo se determina el uso de ASP.NET de 32 bit frente a 64 bit?
- 25. qt aplicación 64 bit windows
- 26. C# Access 64 bit Registro
- 27. ¿Funciona con matlab de 32 o 64 bit?
- 28. Debo usar Python 2.7 32 bit o 64 bit con Windows 7
- 29. Visual Studio 64 bit?
- 30. Conversión Delphi 32 a Delphi XE2 (64 bit)
JaredPar parece estar en desacuerdo - ¿sabes dónde se puede obtener la información? – thecoop
Hmm, tal vez soy un error aquí. Lo investigaré un poco más. –
Actualicé la respuesta con algunos resultados interesantes. –