Boolean vs Byte   zodpovězená otázka

Algoritmy, .NET

Nedávno som si všimol niečo, čo ma dosť nepríjemne zarazilo. Bol som v tom, že k uloženiu premennej typu boolean sa použiva jeden bit. Čiže buď pravda(1) alebo nepravda(0). S hrôzou som zistil, že na uloženie booleanu používa .net tolko bytov, kolko má premenná typu integer. Čiže 4 byty. Načo také plytvanie? Ako som to zistil, začal som používať namiesto boolean typ byte, ktorý splní takú istú funkciu, ale v pamäti zaberie len 1 byte namiesto štyroch. Má niekto predstavu prečo je boolean taký žrút pamäte?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Myslim, ze adresy zarovnane na 4bajty se adresuji rychleji nez kdyz jsou ruzne pohazene po pameti. Na druhou stranu .net je docela velky pametozrout, takze se tomuhle ani nedivim. Navic pameti byva dost a spis jde o tu rychlost. Pro narocne aplikace je tu nativni kod.

Jinak to, ze byte zabira jen 1b neni pravda, dalsi 3b za (nebo pred, podle toho jak se na to divate:) ) tim bytem byvaji prave kvuli tomuhle zarovnani nepouzite. Mala ukazka z .netu 3.5:

static void Main(string[] args)
		{
			byte a = 1, b = 2, c = 3;
			Console.WriteLine("",a,b,c);
		}

A vypis pameti:

0x04BDE8D0  00 00 00 00 00 00 00 00 03 00 00 00 02 00 00 00  
0x04BDE8E0  01 00 00 00 28 37 52 01 df 80 e8 79 36 08 38 00 

Je zcela evidentni, ze i kdyz byte hlasi, ze zere jen 1b, tak ve skutecnosti zabere cele 4.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Nominální velikost proměnné typu Boolean závisí na použité platformě, takže nemůžete tvrdit že velikost je přesně 4 bajty. Například nadeklarujete-li si proměnnou typu Boolean a zjistíte její velikost pomocí funkce Len(), tak na 32-bitovém systému vám vrátí velikost 2 bajty. .NET Framework navíc může z důvodu úspory paměti skládat data co nejblíže k sobě, nebo naopak zarovnávat je na velikost optimální pro zpracování procesorem. Interní implementace datového typu Boolean je reprezentována typem Integer, což je skutečně 4-bajtové číslo. Přesné důvody mi nejsou známy, každopádně jazyk Visual Basic z důvodu kompatibility s předchozími verzemi konvertuje hodnotu True jako -1 a False jako 0. Tudíž -1 by se do typu Byte nevešlo.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Do byte ne, ale do sbyte (signed byte) uz se vejde. A oba teoreticky zerou 1b.

Kde jste zjistil, ze Boolean je implementovan jako int? V reference source pouziva struktura Boolean typ bool k uchovavani dat. Taktez to -1 jako true se mi nezda, jednak beznou praxi je, ze vsechno krome nuly je true, jednak v reference source jsou konstanty True = 1 resp. False = 0.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Já jsem odpovídal proč se nevejde do Byte, ne do SByte.

Zjistil jsem to pomocí .NET Reflectoru, stáhněte si ho a podívejte se sám a zjistíte, že:

Friend Const [True] As Integer = 1Friend Const [False] As Integer = 0

-1 jako True je specialita Visual Basicu (jak jsem již psal z důvodu kompatibility se staršími verzemi VB), v ostatních .NET jazycích tomu tak být nemusí, konkrétně v C# tomu tak není. Každopádně to není v rozporu s tvrzením, že cokoliv kromě nuly je True.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Čo teda používať s ohľadom na šetrenie pamäte? Boolean alebo Byte alebo dokonca SByte? Alebo je to jedno?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

No podle toho, co mi prozradil pohled do pameti, kterou jsem sem psal, tak je to asi jedno. Pokud potrebujete nejak moc setrit kazdy bajt, tak bych byt vami sahl po C nebo jinem nativnim jazyku. Je take mozne, ze existuje nejaky atribut, ktery tyhle veci ovlivnuje.

Kazdopadne uz jen kvuli semantice a citelnosti kodu bych doporucil klasicky bool.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

No jo, on ty konstanty totiz pouziva GetHashCode (jine jsem si nevsiml, resp. v Boolean zadna jina neni), ktery vraci int, tak asi aby se to nemuselo prekonvertovavat.S tim VB.NET mate asi pravdu, VB neovladam, tak nevim. Kazdopadne porad plati pravidlo, ze hodnota je false prave tehdy kdyz je 0. Takze 1 i -1 odpovida true.

Ale dohadovat se o konkretni implementaci Booleanu nema bez realnych zdrojaku smysl (oni totiz ani ty referenci nejsou zrovna moc presne, minimalne v jednom pripade se podstatne lisi od Reflectoru (zkoumal jsem je teda jen jednou)).

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Typ Boolean prostě musí být reprezentován nějakou hodnotou a pokud to není String což by bylo extrémě neefektivní, tak to musí být nějaký číselný typ, v tomto případě Integer.

Z vlastních zkušeností plně důvěřuji Reflectoru, referenční zdrojáky (pokud máte namysli ty Debug symboly pro Visual Studio 2008 co byly nedávno uvolněny) se hodí tak maximálně pro ladění...

Jinak souhlasím s použitím Boolean.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Boolean se ve většině jazyků vnitřně v paměti nereprezentuje jako 1 bit a většinou ani jako 1 bajt. Dnešní procesory nejrychleji pracují s 32bitovými hodnotami (4 bajty), je to prostě daleko rychlejší než pracovat s jednotlivým bajty. Ukládat to jako 1 bit není vhodné, protože bity se nedají adresovat a musel byste s 1 bitem pracovat tak, abyste nezměnil ty ostatní. Pokud potřebujete opravdu hodně booleanů, můžete si napsat vlastní mechanizmus, který je bude ukládat do integerů a pracovat s bity (takže do jednoho integeru se vejde 32 booleanů). Nicméně paměti mají dnešní počítače dost, takže v tomhle takový problém nevidím.

Co se týče VB a magické -1 v hodnotě True, je to přežitek ze starších verzí. Důvodem je to, že 0 má v paměti reprezentaci 00000000 a -1 má reprezentaci 11111111, díky čemuž se mohou udělat nějaké optimalizace při kompilaci, valný význam to sice nemá, ale staré VB to tak měly, takže nám to v novém VB.NET takto zůstalo.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Na práci s velkým množstvím Boolean hodnot by bylo asi nejefektivnější System.Collections.BitArray...

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback