Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: Arthur 18. 12. 2017, 11:55:46

Název: Java: String constants a velikost bajtkódu
Přispěvatel: Arthur 18. 12. 2017, 11:55:46
Ahojte,

nejsem žádný Javaguru, jenom jsem si trochu hrál s optimalizací  kódu a zarazilo mě, že pokud místo opakovaně použitého řetězce textu použiju konstantu-field (např. pomocí public static final String) tak se o poznání zvětší výsledný bytecode místo aby se zmenšil.  Při použití konstanty jako lokální proměnné se to dle očekávání aspoň nepatrně zmenší.

Co je příčinou? je tam nějaká režie podobně jako u dědičnosti (přesunutí společného kódu dvou tříd do nově vzniklé společné nadtřídy se "vyplatí" jen když je toho kódu dostatek) ?
Název: Re:Java: String constants a velikost bajtkódu
Přispěvatel: borekz 18. 12. 2017, 13:21:40
Zkus dát private místo public.
Název: Re:Java: String constants a velikost bajtkódu
Přispěvatel: Phi 18. 12. 2017, 13:52:37
Dobrý den, to jsou v podstatě dvě spolu nesouvisející věci.
a) existuje něco co se nazývá string constant pool. Stringy v Javě jsou immutable wrappery okolo char []. Toho se využívá k tomu, že Stringy se stejným obsahem odkazují na stejné char pole.
b) bytecode pro přístup k různým typům proměnných má rozdílnou délku v bytech. Přístup k lokálním proměnným produkuje (AFAIK) nejkratší (a nejrychlejší) bytecode.
Název: Re:Java: String constants a velikost bajtkódu
Přispěvatel: perceptron 18. 12. 2017, 15:26:33
styri byty zabera referencia vo fielde

konstantne stringy su internalizovane do string constant poolu (vid Phi).

ak robite mikrooptimalizacie takymto sposobom...good luck...




Název: Re:Java: String constants a velikost bajtkódu
Přispěvatel: Arthur 18. 12. 2017, 16:11:45
Dobrý den, to jsou v podstatě dvě spolu nesouvisející věci.
a) existuje něco co se nazývá string constant pool. Stringy v Javě jsou immutable wrappery okolo char []. Toho se využívá k tomu, že Stringy se stejným obsahem odkazují na stejné char pole.
b) bytecode pro přístup k různým typům proměnných má rozdílnou délku v bytech. Přístup k lokálním proměnným produkuje (AFAIK) nejkratší (a nejrychlejší) bytecode.

OK, díky, teď už mi to dává větší smysl.

ak robite mikrooptimalizacie takymto sposobom...good luck...

dobře a jak to tedy udělat lépe?  Chci mít textovou konstantu přístupnou alespoň v podtřídách (protected) nebo ideálně kdykoliv a kdekoliv (public static) abych neměl tentýž řetězec naflákaný na padesáti místech kódu a zároveň nechci aby tím bytecode bobtnal nebo zpomaloval ...
Název: Re:Java: String constants a velikost bajtkódu
Přispěvatel: perceptron 18. 12. 2017, 16:20:20
textova konstanta je public static final alebo private static final

1 bud robite generator bajtkodu ale to by sa taketo otazky nepytali
2 xor robite beznu aplikaciu a tam su taketo mikrooptimalizacie nahouby.

co z toho je pravda?

velkost bajtkodu zalezi od kompilatora / pouzivaneho jvm / pocasia vonku. /fyi java language specification nehovori nic o velkosti jednotlivych datatypes/

Název: Re:Java: String constants a velikost bajtkódu
Přispěvatel: Filip Jirsák 18. 12. 2017, 16:21:11
Chci mít textovou konstantu přístupnou alespoň v podtřídách (protected) nebo ideálně kdykoliv a kdekoliv (public static) abych neměl tentýž řetězec naflákaný na padesáti místech kódu
Dejte to do nějaké třídy jako public static final konstantu.

zároveň nechci aby tím bytecode bobtnal
Že to nechcete má nějaký důvod? Nebo je to jenom rozmar? Pokud k tomu nemáte nějaký dobrý důvod, neřešte to.

nebo zpomaloval ...
Tak to neřešte, JVM si s tím pravděpodobně poradí daleko lépe. Pokud byste to přesto chtěl řešit, tak to neřešte. A pokud byste to i přesto chtěl řešit, zapněte si profiler a změřte, co aplikaci skutečně zpomaluje, a pak se zaměřte na to.
Název: Re:Java: String constants a velikost bajtkódu
Přispěvatel: tisnik 18. 12. 2017, 16:37:33
Pomuze ti i vystup z:

Kód: [Vybrat]
java -constants -verbose TvojeTrida.class
Mrkni kolikrat je ten retezec na ve string poolu a jak se ziskava jeho reference. Nebo klidne posli vystup z toho prikazu nahore, ja to okomentuju :)
Název: Re:Java: String constants a velikost bajtkódu
Přispěvatel: Arthur 18. 12. 2017, 17:01:09
Dejte to do nějaké třídy jako public static final konstantu.
Jo přesně takhle to dělám
zároveň nechci aby tím bytecode bobtnal nebo zpomaloval ...
Že to nechcete má nějaký důvod? Nebo je to jenom rozmar? Pokud k tomu nemáte nějaký dobrý důvod, neřešte to.
Přesně tak, rozmar. Prostě jsem čekal, že se to bude nějak chovat, a rozčilovalo mě, že je to obráceně a myslel jsem, že dělám něco blbě.  Každopádně jsem zas o něco chytřejší, takže díky.
Název: Re:Java: String constants a velikost bajtkódu
Přispěvatel: Arthur 18. 12. 2017, 17:09:41
textova konstanta je public static final alebo private static final

1 bud robite generator bajtkodu ale to by sa taketo otazky nepytali
2 xor robite beznu aplikaciu a tam su taketo mikrooptimalizacie nahouby.

co z toho je pravda?

velkost bajtkodu zalezi od kompilatora / pouzivaneho jvm / pocasia vonku. /fyi java language specification nehovori nic o velkosti jednotlivych datatypes/

Používám samozřejmě final, to jsem zapoměl uvést.  Jedná se běžnou aplikaci a šlo mi hlavně o pochopení problému, jasně že mě těch pár stovek bajtů nezabije :-) Už jsem smířen s tím, že je to nutná daň za lepší udržovatelnost kódu.
Název: Re:Java: String constants a velikost bajtkódu
Přispěvatel: Phi 18. 12. 2017, 17:12:48
dobře a jak to tedy udělat lépe?  Chci mít textovou konstantu přístupnou alespoň v podtřídách (protected) nebo ideálně kdykoliv a kdekoliv (public static) abych neměl tentýž řetězec naflákaný na padesáti místech kódu
To je dobrý nápad a řeší se to obvykle pomocí static final
Citace
a zároveň nechci aby tím bytecode bobtnal nebo zpomaloval ...
Tohle je samo o sobě taky hezký nápad, ale...
- Pokud budete aplikaci distribuovat v JAR kontejneru, stejně bude zapakovana Zip kompresí a pokud ty výsledné classy zkratíte o bajty, po kompresi bude zisk v bitech, jestli vůbec
- Moderní JVM optimalizuje fakt dobře a i když se vám podaří o něco zrychlit na vašem konkrétním počítači s konkrétní verzí Javy, s jinou verzí Javy to může být jinak. Navíc vstupují do hry věci jako cache CPU a atd. Mikrooptimalizace měli smysl v J2ME a dnes možná v Java kartách ale jinak jsou fakt pasé.
- Smysl má optimalizovat datové struktury a algoritmy a na to je dobrý profiler.
Název: Re:Java: String constants a velikost bajtkódu
Přispěvatel: anonym 18. 12. 2017, 17:18:16
Tady si někdo stěžuje na Javu? Kdo měl tu drzost?

Pokud potřebuješ nějaký řetězec používat na 50 různých místech mimo záběr třídy, tak to už je na zvážení umístit ho do properties nebo do nějaké specifické třídy pro takovéto řetězce.
Název: Re:Java: String constants a velikost bajtkódu
Přispěvatel: Kit 18. 12. 2017, 17:52:09
Pokud potřebuješ nějaký řetězec používat na 50 různých místech mimo záběr třídy, tak to už je na zvážení umístit ho do properties nebo do nějaké specifické třídy pro takovéto řetězce.

Spíš přemístit potřebnou funkcionalitu do třídy k tomu řetězci a ponechat ho jako privátní.
Název: Re:Java: String constants a velikost bajtkódu
Přispěvatel: kvr kvr 18. 12. 2017, 17:59:07
Definice proměnné zabírá nějaké místo. Má své místo, její název zabírá nějaké místo a odkazy na ni zabírají nějaké místo (to je jen index co tabulky řetězců).

Podobně, když zorganizuju kód do několika metod, místo, abych splácal všechno do jedné - taky bude ve výsledku větší (v bytecode).

JIT udělá práci za vás a splácá všechno dohromady, takže výsledek bude stejný. Tedy žádný vliv na výkon a malý vliv na paměť (stále bude formálně existovat proměnná daného jména).
Název: Re:Java: String constants a velikost bajtkódu
Přispěvatel: Filip Jirsák 18. 12. 2017, 20:20:11
Spíš přemístit potřebnou funkcionalitu do třídy k tomu řetězci a ponechat ho jako privátní.
Co když je tím řetězcem třeba UTF-8 a označuje to kódování dat na vstupu nebo výstupu? Tam, kde to jde, používám Charset (ale to je jen konstanta jiného typu), ale spousta metod má na vstupu jako parametr pro kódování jenom String.
Název: Re:Java: String constants a velikost bajtkódu
Přispěvatel: Kit 18. 12. 2017, 20:53:40
Spíš přemístit potřebnou funkcionalitu do třídy k tomu řetězci a ponechat ho jako privátní.
Co když je tím řetězcem třeba UTF-8 a označuje to kódování dat na vstupu nebo výstupu? Tam, kde to jde, používám Charset (ale to je jen konstanta jiného typu), ale spousta metod má na vstupu jako parametr pro kódování jenom String.

Taková "co když" bývají docela zábavná. Use Case neznáme, tedy ani nevíme, zda nějaké "co když" nastane.
Název: Re:Java: String constants a velikost bajtkódu
Přispěvatel: Filip Jirsák 18. 12. 2017, 21:35:53
Spíš přemístit potřebnou funkcionalitu do třídy k tomu řetězci a ponechat ho jako privátní.
Co když je tím řetězcem třeba UTF-8 a označuje to kódování dat na vstupu nebo výstupu? Tam, kde to jde, používám Charset (ale to je jen konstanta jiného typu), ale spousta metod má na vstupu jako parametr pro kódování jenom String.

Taková "co když" bývají docela zábavná. Use Case neznáme, tedy ani nevíme, zda nějaké "co když" nastane.
Nechtěl jsem prodlužovat komentář spoustou příkladů, předpokládal jsem, že každého napadne nějaký z jeho praxe. Tedy několik use case:


Stačí takhle?