Spørsmål om Structs

stemmer
7

MSDN sier at en klasse som vil være 16 byte eller mindre ville være bedre håndtert som en struct [trenger referanse] .
Hvorfor det?
Betyr det at hvis en struct er over 16 bytes det er mindre effektiv enn en klasse eller er det det samme?
Hvordan avgjør dere om klassen din er under 16 bytes?
Hva begrenser en struct fra å opptre som en klasse? (foruten å ikke tillate parameterless konstruktører)

Publisert på 20/03/2009 klokken 18:02
kilden bruker
På andre språk...                            


7 svar

stemmer
6

Det finnes et par forskjellige svar på dette spørsmålet, og det er litt subjektivt, men noen grunner jeg kan tenke på er:

  • Structs er verditype, klasser er referansetypen. Hvis du bruker 16 byte for total lagringsplass, er det sannsynligvis ikke verdt det å skape minne referanser (4 til 8 bytes) for hver enkelt.
  • Når du har veldig små objekter, kan de ofte bli skjøvet på IL stabelen, i stedet for referanser til objektene. Dette kan virkelig få fart på noen kode, som du eliminere en minne deferanseoperasjon på callee side.
  • Det er litt ekstra "fluff" assosiert med klasser i IL, og hvis datastruktur er svært liten, ville ingenting av dette lo brukes uansett, så det er bare ekstra junk du ikke trenger.

Den viktigste forskjellen mellom en struct og en klasse, skjønt, er at structs er verditype og klasser er referansetype.

Svarte 20/03/2009 kl. 18:15
kilden bruker

stemmer
3

Med "effektiv", er de sannsynligvis snakker om hvor mye minne som trengs for å representere klassen eller struct.

På den 32-bits plattform, å allokere et objekt krever et minimum av 16 bytes. På en 64-bits plattform, er den minste gjenstand størrelse 24 byte. Så, hvis du ser på det rent fra mengden minne som brukes, vil en struct som inneholder mindre enn 16 byte data være "bedre" enn tilsvarende klasse.

Men hvor mye minne som brukes er ikke hele historien. Verdi typer (structs) er fundamentalt annerledes enn referanse typer (klasser). Structs kan være upraktisk å jobbe med, og kan faktisk føre til ytelsesproblemer hvis du ikke er forsiktig.

Den virkelige svaret, selvfølgelig, er å bruke det som fungerer best i din situasjon. I de fleste tilfeller vil du være mye bedre å bruke klasser.

Svarte 20/03/2009 kl. 18:48
kilden bruker

stemmer
2

Sjekk denne linken, fant jeg det på ett av svarene på det i dag: .NET Type Internals . Du kan også prøve å søke SO og Googling for "referansetyper vs verdityper" for forskjeller mellom structs og klasser.

Hva begrenser en struct fra å opptre som en klasse?

Det er mange forskjeller. Du kan ikke arve fra en struct, for eksempel.

Du kan ikke ha virtuelle metoder, så du kan ikke bruke en struct å implementere et grensesnitt. Instansmetoder i structs kan få tilgang til struct private felt, men bortsett fra at de oppfører seg mye som auxilirary "hjelper" funksjoner (for uforanderlige structs, de noen ganger ikke engang trenger å få tilgang til private data). Så jeg synes de er ikke så nær som "verdifulle" som klassemetoder.

Svarte 20/03/2009 kl. 18:15
kilden bruker

stemmer
0

Kopiering av en forekomst av en struct tar mindre tid enn å lage en ny forekomst av en klasse og kopiering av data fra en gammel, men klasse tilfeller kan deles og struct tilfeller ikke kan. Dermed "structvar1 = structvar2" krever kopiering ny struct eksempel, mens "classvar1 = classvar2" lar classvar1 og classvar2 refererer til samme struct eksempel (uten å skape en ny).

Koden for å håndtere etableringen av nye struct tilfeller er optimalisert for størrelser opp til 16 byte. Større structs håndteres mindre effektivt. Structs er en seier i tilfeller hvor hver variabel som har en struct vil holde en uavhengig instans (dvs. det er ingen grunn til å forvente at noen spesielle to variablene vil holde identiske tilfeller); de er ikke mye av en seier (hvis de er en seier i det hele tatt) i tilfeller der mange variabler kunne holde samme instans.

Svarte 20/01/2011 kl. 21:36
kilden bruker

stemmer
0

Structs er forskjellige fra klassene fordi de er lagret på stakken, og ikke på haugen. Det betyr at hver gang du kaller en metode med struct som parameter, en kopi opprettes og sendes til metoden. Det er derfor store structs er ekstremt ineffektiv.

Jeg ville aktivt fraråde å bruke structs likevel, fordi det kan føre til at noen subtile feil: f.eks når du endrer et felt av en struct, det kommer ikke til å bli reflektert for den som ringer (fordi du bare endret kopi) - som er en helt annen adferd til klasser.

Så de 16 bytes jeg tror er en rimelig maksimal størrelse på en struct, men likevel i de fleste tilfeller er det bedre å ha en klasse. Hvis du likevel ønsker å opprette en struct, prøv å gjøre det uforanderlige minst.

Svarte 20/03/2009 kl. 18:17
kilden bruker

stemmer
0

Dette er på grunn av forskjellig måte at CLR håndterer structs og klasser. Structs er verdityper som betyr at de lever på bunken i stedet for i den administrerte haug. Det er en god tommelfingerregel å holde structs lite fordi når du begynner å passere dem som metode argumenter du vil pådra overhead som structs kopieres i sin helhet når sendes til en metode.

Siden klasser passere en kopi av deres henvisning til metoder de ikke medfører mye mindre overhead når de anvendes som metode argumenter.

Den beste måten å bestemme størrelsen på klassen er å totalt antall byte som kreves av alle medlemmene i klassen pluss en ekstra 8 byte for CLR overhead ting (sync blokk indeksen og referanse til hvilken type objekt).

Svarte 20/03/2009 kl. 18:16
kilden bruker

stemmer
0

I minnet, vil struct holde dataene direkte, mens en klasse vil oppføre seg mer som en peker. Det alene gjør en viktig forskjell, ettersom passerer struct som en parameter til en metode vil passere dens verdier (kopier dem på stabelen), mens klassen vil passere henvisning til verdiene. Hvis struct er stor, vil du bli kopiere mye av verdiene på hver metode samtale. Når det er veldig liten kopiere verdiene og bruke dem direkte blir sannsynligvis raskere enn å kopiere pekeren og måtte hente dem fra et annet sted.

Om begrensninger: du kan ikke tilordne den til null (selv om du kan bruke Kan ha nullverdier <>), og du må initialisere det med en gang.

Svarte 20/03/2009 kl. 18:13
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more