| 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: 12 let
|
|||
0