Autor | Zpráva | ||
---|---|---|---|
martin20a Profil |
#1 · Zasláno: 8. 6. 2014, 12:21:22
Zdravím,
platí v PHP obdoba jak v Java/C++, že když mám konstanty či statické atributy třídy, tak náročnost časová na získání statického atributu těmito způsoby: class A { public static $x = 1; } $a = new A(); // 1 echo $a->x; // 2 A::$x; U 2 způsobu, se předpokládám podívá do tabulky načtených tříd najde třídu a ten atribut. Ale zajímalo by mě jak je to u způsobu 1 - čili to se dle mého podívá na adresu třídy a pak se podívá na odkaz třídy do tabulky tříd a tam najde ten atribut, čili by to mělo být náročnější, nebo alespoň zdlouhavější, než způsob č.1, je tak? Je jasné, že tne rozdíl bude cca v nano sekundách, ale i tak by mě zajímalo co je lepší použít, jelikož třeba právě Netbeans ti dává varování, že je lepší použití č.2 než č.1 pro Java. Díky :-) |
||
juriad Profil |
martin20a:
První možnost je blbě (v PHP), tedy nad ní nemá smysl uvažovat. Static properties cannot be accessed through the object using the arrow operator ->. V Javě se používá druhá možnost především z důvodu přehlednosti, aby šlo na první pohled odlišit třídní a instanční proměnnou. Rychlost provádění je v Javě a C++ v obou případech stejná; oba jazyky se kompilují a provádí se některé optimalizace. (U Javy jsem si to právě ověřil.) Javový kód M m = new M(); System.out.println(m.x); System.out.println(M.x); /* L7 */ 0 new 1; 3 dup; 4 invokespecial 21; /* M() */ 7 astore_1; /* m */ /* L8 */ 8 getstatic 22; /* java.lang.System.out */ 11 getstatic 10; /* M.x */ 14 invokevirtual 28; /* void println(int arg0) */ /* L9 */ 17 getstatic 22; /* java.lang.System.out */ 20 getstatic 10; /* M.x */ 23 invokevirtual 28; /* void println(int arg0) */ |
||
martin20a Profil |
juriad:
Jo to jsem napsal trochu blbě. Já jsem ve skutečnosti chtěl něco jiného, ale už si nedokážu vzpomenout jak to přesně bylo -> jsem si vzpomenul blbě očividně. :-) Nicméně díky za ukázku, zeptal bych se ještě na dvě věci: 1) Jak mohu dosáhnout v netbeans/eclipse/... dumpu z překladu? 2) To co jsi zaslal je plný "dump", nebo jen jsi z toho vybral toto, jde mi hlavně o to, že při "m.x" bych řekl, že se musí dostat první přes adresu instance na přesnou adresu třídy? A u "M.x" se musí ta adresa hledat v tabulce, takže to asi bude na stejno, tak jak tak se musí najít. Což by nasvědčovalo tomu, že kdybych 1.000.000x zavolal "m.x" a "M.x", tak by lepší výsledek mohl dostat "m.x", jelikož tam to hledání v tabulce proběhne jen 1x, jestli uvažuji správně. Je tedy ještě možné, že ten dump takto vypadá díky optimilizaci, že si každé "m.x" převádí na "M.x" :-) Zrovna se učím na jednu zkoušku a tak si to propojuji s tím co dělám v "programovacím jazyce" PHP s tím co nás učí na příkladech java,c++,... :-)) |
||
juriad Profil |
Používám Eclipse a programuji v Javě. Doinstaloval jsem si doplněk Bytecode Visualizer. Pak stačí jakýkoli .class soubor otevřít v tomto editoru.
Celý zdroják je: public class M { static int x = 5; public static void main(String[] args) { M m = new M(); System.out.println(m.x); System.out.println(M.x); } } Celý vizualizovaný bytecode: /* ******************************************** */ /* Generated by Dr. Garbage Bytecode Visualizer */ /* http://www.drgarbage.com */ /* Version: 4.3.5.201402051140 */ /* Class retrieved from: Filesystem */ /* Retrieved on: 2014-06-08 13:19:02.021 */ /* ******************************************** */ /* class file format version 51.0 (java 1.7) */ public class M { /* compiled from M.java */ static int x; static { /* L4 */ 0 iconst_5; 1 putstatic 10; /* M.x */ 4 return; } public M() { /* L2 */ 0 aload_0; /* this */ 1 invokespecial 15; /* java.lang.Object() */ 4 return; } public static void main(java.lang.String[] args) { /* L7 */ 0 new 1; 3 dup; 4 invokespecial 21; /* M() */ 7 astore_1; /* m */ /* L8 */ 8 getstatic 22; /* java.lang.System.out */ 11 getstatic 10; /* M.x */ 14 invokevirtual 28; /* void println(int arg0) */ /* L9 */ 17 getstatic 22; /* java.lang.System.out */ 20 getstatic 10; /* M.x */ 23 invokevirtual 28; /* void println(int arg0) */ /* L10 */ 26 return; } } Právěže javový kompilátor umí dokázat, že m.x je ve skutečnosti odkaz na statické pole (je součástí veřejného kontraktu dané třídy = je vždy známé), tedy ten mezikrok (který ani neumíš bez reflexe vyjádřit) vypustí. Ta „optimalizace“ je nutná, protože (nejspíš) neexistuje instrukce ani sekvence instrukcí v bytecode, které by přistoupily ke statické proměnné instančně. Instrukce getfield (pro instanční proměnné) vezme ze zásobníku referenci na objekt a nalezne v něm hodnotu proměnné jejíž název dostane jako parametr a zapíše její hodnotu na zásobník.
Instrukce getstatic (pro statické proměnné) nebere nic ze zásobníku a nalezne hodnotu proměnné jejíž název dostane jako parametr a zapíše její hodnotu na zásobník.
|
||
martin20a Profil |
#5 · Zasláno: 8. 6. 2014, 13:52:43
Díky :)
|
||
Časová prodleva: 11 let
|
0