Článek
Když má text 10 000 znaků, svádí to k jednoduchému závěru: soubor bude mít 10 000 bajtů. U čistého ASCII to opravdu může vyjít přesně. Jakmile ale do stejného textu pustím české háčky a čárky, rovnost se rozpadne.
Pro tento článek jsem udělal jednoduchý reprodukovatelný test. Připravený český odstavec jsem opakoval a ořízl přesně na 10 000 znaků a vytvořil druhou verzi se stejným obsahem, ale bez diakritiky. Obě verze měly v Pythonu shodně 10 000 Unicode kódových bodů. Po uložení do UTF-8 však první měla 10 967 bajtů a druhá 10 000. Rozdíl byl 967 bajtů, tedy 9,67 %.
Metoda: stejné znaky, jiný počet bajtů
Základ testu byl záměrně prostý. Neřešil jsem kompresi, velikost dokumentu DOCX, metadata ani tokenizaci jazykového modelu. Měřil jsem pouze délku textu po zakódování do UTF-8.
len(text)
len(text.encode("utf-8"))
Verzi bez diakritiky jsem vytvořil Unicode normalizací NFD a odstraněním slučovacích značek. U tohoto konkrétního českého vzorku tím zůstal zachovaný počet 10 000 kódových bodů. Surová data a postup jsou proto snadno zopakovatelné v několika řádcích Pythonu.
Výsledek hlavního vzorku: bez diakritiky 10 000 B, s diakritikou 10 967 B. Česká verze tedy zabrala o 967 B více. Tenhle rozdíl není univerzální „daň češtiny“; závisí na tom, kolik znaků mimo ASCII konkrétní text obsahuje.
Proč č často zabere dva bajty a obyčejné c jen jeden
UTF-8 je proměnlivě dlouhé kódování. Znaky z původního ASCII rozsahu U+0000 až U+007F se zapisují jedním bajtem. Další části Unicode potřebují dva, tři nebo čtyři bajty podle hodnoty kódového bodu.
To je přesně důvod, proč se česká diakritika v našem testu projeví na velikosti. Písmena jako č, ř, š, ž, ě nebo ů leží mimo ASCII a v běžném prekomponovaném zápisu UTF-8 zabírají dva bajty. Jejich varianty bez diakritiky c, r, s, z, e nebo u jsou v ASCII a stačí jim jeden bajt.
Na jednoduchých extrémech je rozdíl vidět ještě ostřeji:
10 000 znaků „a“ = 10 000 bajtů v UTF-8.
10 000 znaků „č“ = 20 000 bajtů v UTF-8.
10 000 emoji 🙂 = 40 000 bajtů v UTF-8.
Tři řetězce mohou mít podle jednoduchého počítání stejných 10 000 kódových bodů, ale jejich bajtová velikost se liší čtyřnásobně.
„Znak“ je zrádné slovo
Unicode navíc upozorňuje, že otázka „kolik má řetězec znaků“ nemá vždy jedinou odpověď. Můžeme počítat bajty, kódové jednotky, kódové body nebo to, co uživatel vnímá jako jeden grafický znak. U češtiny je většina běžných písmen s diakritikou dostupná jako jeden prekomponovaný kódový bod, ale stejný vzhled může někdy vzniknout i složením základního písmene a kombinující značky.
č → U+010D → 2 bajty v UTF-8
c + ◌̌ → U+0063 + U+030C → 3 bajty v UTF-8
Na obrazovce mohou oba zápisy vypadat stejně. Uvnitř souboru ale nejde o stejnou sekvenci bajtů. Proto je při technických limitech důležité vědět, zda systém omezuje počet znaků, kódových bodů, nebo přímo bajtů.
Tohle není článek o AI tokenech
Na Médiu už existuje text, který řeší zajímavý paradox češtiny bez diakritiky z pohledu tokenizace jazykových modelů. Tam může verze bez háčků a čárek paradoxně spotřebovat více tokenů, protože tokenizér nepočítá text stejným způsobem jako souborový systém.
Můj test řeší jinou otázku: kolik fyzických bajtů vytvoří UTF-8. Na téhle vrstvě je výsledek předvídatelný podle kódových bodů a jejich UTF-8 reprezentace. Token může pokrýt část slova, celé slovo nebo jiný kus textu; bajt je základní osmibitová jednotka uložených dat. Míchat tyto dvě metriky by vytvořilo přesně opačný závěr, než jaký data skutečně ukazují.
Kdy na tom záleží v praxi
U běžného článku o několika kilobajtech člověk rozdíl vůbec řešit nemusí. Důležitý začne být tam, kde systém stanovuje limit v bajtech: při ukládání do databází, při přenosových protokolech, v některých API nebo při práci s pevně velkými buffery. Řetězec o 100 znacích nemusí znamenat 100 bajtů.
Stejně tak je dobré neplést velikost čistého textu s velikostí dokumentu. Soubor DOCX obsahuje XML, styly a další data; HTML přidává značky; komprese může výsledek zase zmenšit. Čísla 10 000 a 10 967 z tohoto testu proto popisují přímo UTF-8 bajty zadaného řetězce, nic víc a nic méně.
Verdikt: počítadlo znaků není měřič velikosti
Nejzajímavější na výsledku není samotných 967 bajtů navíc. Je to fakt, že oba texty vypadají z pohledu jednoduchého počítadla stejně dlouhé: 10 000 znaků. Teprve ve chvíli, kdy je převedu do UTF-8, se ukáže, že česká diakritika v mém konkrétním vzorku zvedla velikost o 9,67 %.
Počet znaků a počet bajtů jsou zkrátka dvě různé otázky. Dokud pracujeme jen s anglickým ASCII, snadno získáme pocit, že jsou stejné. Čeština tenhle pohodlný omyl rozbije hned prvními háčky a čárkami.
Zdroje a metodika
Unicode 18 – Chapter 2, Encoding Forms — UTF-8 je proměnlivě dlouhé kódování; ASCII zůstává jednobajtové, další znaky používají více bajtů.
Unicode Technical Report #17 – Character Encoding Model — Přehled kódových jednotek a rozsahů 1–4 bajtů v UTF-8.
Unicode FAQ – Characters and Combining Marks — Rozlišuje počítání bajtů, kódových jednotek, kódových bodů a uživatelsky vnímaných znaků.
Python 3 – str.encode — Použitá metoda pro reprodukovatelné převedení řetězce do UTF-8 a spočítání bajtů.






