Java: String constants a velikost bajtkódu

Arthur

  • ***
  • 171
    • Zobrazit profil
    • E-mail
Java: String constants a velikost bajtkódu
« kdy: 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) ?


borekz

  • ****
  • 493
    • Zobrazit profil
    • E-mail
Re:Java: String constants a velikost bajtkódu
« Odpověď #1 kdy: 18. 12. 2017, 13:21:40 »
Zkus dát private místo public.

Phi

Re:Java: String constants a velikost bajtkódu
« Odpověď #2 kdy: 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.

perceptron

Re:Java: String constants a velikost bajtkódu
« Odpověď #3 kdy: 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...





Arthur

  • ***
  • 171
    • Zobrazit profil
    • E-mail
Re:Java: String constants a velikost bajtkódu
« Odpověď #4 kdy: 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 ...


perceptron

Re:Java: String constants a velikost bajtkódu
« Odpověď #5 kdy: 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/


Re:Java: String constants a velikost bajtkódu
« Odpověď #6 kdy: 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.

tisnik

Re:Java: String constants a velikost bajtkódu
« Odpověď #7 kdy: 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 :)

Arthur

  • ***
  • 171
    • Zobrazit profil
    • E-mail
Re:Java: String constants a velikost bajtkódu
« Odpověď #8 kdy: 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.

Arthur

  • ***
  • 171
    • Zobrazit profil
    • E-mail
Re:Java: String constants a velikost bajtkódu
« Odpověď #9 kdy: 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.

Phi

Re:Java: String constants a velikost bajtkódu
« Odpověď #10 kdy: 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.

anonym

Re:Java: String constants a velikost bajtkódu
« Odpověď #11 kdy: 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.

Kit

Re:Java: String constants a velikost bajtkódu
« Odpověď #12 kdy: 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í.

Re:Java: String constants a velikost bajtkódu
« Odpověď #13 kdy: 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).

Re:Java: String constants a velikost bajtkódu
« Odpověď #14 kdy: 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.