Domanda

Perché un booleano consuma 4 byte e un char 2 byte nel framework .NET? Un booleano dovrebbe richiedere 1 bit o almeno essere più piccolo di un carattere.

È stato utile?

Soluzione

È una questione di allineamento della memoria. Le variabili a 4 byte funzionano più velocemente di quelle a 2 byte. Questo è il motivo per cui dovresti usare int invece di byte o short per contatori e simili.

È necessario utilizzare variabili a 2 byte solo quando la memoria è una preoccupazione maggiore della velocità. E questo è il motivo per cui char (che è Unicode in .NET) richiede due byte anziché quattro.

Altri suggerimenti

Informazioni su boolean

La maggior parte delle altre risposte sbagliano: l'allineamento e la velocità sono i motivi per cui un programmatore dovrebbe attenersi a int per i contatori di loop, non perché il compilatore può rendere un byte largo 4 byte. Tutti i tuoi ragionamenti, infatti, si applicano a byte, short e booleano.

Almeno in C #, bool (o System.Boolean) è una struttura incorporata larga 1 byte, che può essere automaticamente inscatolata, quindi hai un oggetto (che ha bisogno di due parole di memoria per essere rappresentato, per lo meno, cioè 8/16 byte su ambienti a 32/64 bit rispettivamente) con un campo (almeno un byte) più una parola di memoria per puntare ad esso, cioè in totale almeno 13/25 byte.

Questa è davvero la prima voce di Google su " tipi primitivi C # " ;. http://msdn.microsoft.com/en-us/ biblioteca / ms228360 (VS.80) aspx

Anche il link citato ( http://geekswithblogs.net/cwilliams /archive/2005/09/18/54271.aspx ) afferma inoltre che un valore booleano, secondo lo standard CLI, richiede 1 byte.

In realtà, tuttavia, l'unico posto in cui questo è visibile è su array di booleani - n booleani richiederebbe n byte. Negli altri casi, un valore booleano può richiedere 4 byte.

  • All'interno di una struttura, la maggior parte dei tempi di esecuzione (anche in Java) allineava tutti i campi a un limite di 4 byte per le prestazioni. Il Monty JVM per dispositivi integrati è più saggio - immagino che riordini i campi in modo ottimale.
    • Sullo stack di frame / operando locale per l'interprete, nella maggior parte dell'implementazione, per le prestazioni, una voce di stack è larga una sola parola di memoria (e forse su .NET deve essere larga 64 bit per supportare double e long, che su .NET utilizza solo 1 voce di stack anziché 2 in Java). Un compilatore JIT può invece utilizzare 1 byte per i locali booleani mantenendo allineati altri var, riordinando i campi senza impatto sulle prestazioni, se ne vale la pena.

Informazioni su char

char sono due byte perché quando è richiesto il supporto per l'internazionalizzazione, usare internamente caratteri a due byte è la scommessa più sicura. Ciò non è direttamente correlato alla scelta di supportare Unicode, ma alla scelta di attenersi a UTF-16 e al piano multilingue di base. In Java e C #, puoi sempre presumere che un carattere logico si adatti a una variabile di tipo carattere.

Questo perché in un ambiente a 32 bit, la CPU può gestire valori a 32 bit più veloci dei valori a 8 o 16 bit, quindi questo è un compromesso di velocità / dimensione. Se devi risparmiare memoria e hai una grande quantità di bool, usa uint se salva i tuoi booleani come bit di uint s a 4 byte. I caratteri sono larghi 2 byte poiché contengono caratteri Unicode a 16 bit.

Indipendentemente dalla minore differenza nella memoria, l'utilizzo di Boolean per valori vero / falso sì / no è importante per gli sviluppatori (incluso te stesso, quando devi rivisitare il codice un anno dopo), perché riflette più accuratamente le tue intenzioni. Rendere il tuo codice più comprensibile è molto più importante del salvataggio di due byte.

Rendere il tuo codice più accurato riflette le tue intenzioni riduce anche la probabilità che alcune ottimizzazioni del compilatore abbiano un effetto negativo. Questo consiglio trascende piattaforme e compilatori.

Dovresti anche usare booleano per aiutare a scrivere codice manutenibile. Se guardo il codice per vedere che qualcosa è un valore booleano, vale la pena risparmiare memoria per capire che stai usando char come booleano.

Ho trovato questo: " In realtà, un valore booleano è di 4 byte, non 2. Il motivo è che questo è ciò che il CLR supporta per il valore booleano. Penso che sia quello che fa perché i valori a 32 bit sono molto più efficienti da manipolare, quindi il compromesso tempo / spazio vale, in generale, la pena. Dovresti usare la classe bit vector (dimentica dove si trova) se devi inceppare un mucchio di bit insieme ... "

È scritto da Paul Wick su http://geekswithblogs.net /cwilliams/archive/2005/09/18/54271.aspx

Prima di tutto dovresti usare un profiler per determinare dove hai problemi di memoria, IMHO.

La memoria è un problema solo se si dispone di una vasta gamma di bit, nel qual caso è possibile utilizzare la classe System.Collections.BitArray.

È perché Windows e .Net hanno utilizzato Unicode (UTF 16) sin dall'inizio come set di caratteri interno. UTF 16 utilizza 2 byte per carattere o una coppia di 2 byte per carattere, ma solo se richiesto in quanto codifica a larghezza variabile .

" Per i caratteri nel BMP (Basic Multilingual Plane) la codifica risultante è una singola parola a 16 bit. Per i caratteri negli altri piani, la codifica si tradurrà in una coppia di parole a 16 bit "

La mia ipotesi riguardo ai booleani sarebbe che sono quattro byte poiché il registro predefinito è 32 bit e questa sarebbe la dimensione minima. Net potrebbe fare un'operazione logica su in modo efficiente, a meno che non utilizzi operazioni bit a bit.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top