Programowanie obiektowe - Java vs Python

0

Cześć,
wydawało mi się, że zrozumiałem na czym polega referencja w programowaniu obiektowym - jest to powiązanie, które wskazuje na obiekt w pamięci. Jednak przy okazji zapoznawania się z Wrapperami zacząłem się zastanawiać na czym polega różnica z referencją w Javie, a Pythonie.

Z poniższego załącznika wygląda, to tak jakby w Pythonie referencja zmiennych x oraz y również były referencjami do tego samego obiektu znajdującego się w pamięci.
Przechwytywanie.PNG

Czy ktoś mógłby wytłumaczyć na czym polega różnica w referowaniu w Javie oraz w Pythonie?

1

Chyba kierunkiem się różnią tak na chłopski rozum.

3

spróbuj z większymi liczbami, np. miliardem

2

To są referencje do tego samego obiektu - optymalizacja dla małych liczb, które są często używane. Zamiast tworzenia nowych obiektów korzysta się z predefiniowanej puli [-5, 256].
W Javie też jest taka optymalizacja, przykładowo gdybyś przyrównał referencje dla dwóch Integerów w zakresie [-127, 128].

2

@marzappo nie wiem co dowodzi ten twój przykład. Zrób w Javie String x = "1"; String y = "1"; i zobacz że też będą pokazywać na to samo. Analogicznie Integer x = 1; Integer y = 1;

3

@marzappo: to co pokazałeś jest trochę bardziej złożone i nie odnosi się tylko do adresowania pamięci. Rozważmy taki przykład:

koziolek@koziolek-desktop3 ~/workspace/python $ python3
Python 3.8.10 (default, Nov 26 2021, 20:14:08) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> id("geek")
140235900763696
>>> quit()
koziolek@koziolek-desktop3 ~/workspace/python $ python3
Python 3.8.10 (default, Nov 26 2021, 20:14:08) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> id("geek")
140537457438256
>>> 

Dwa uruchomienia interpretera ten sam rezultat. Pytanie, jaka jest szansa, że obiekt trafi dokładnie w ten sam adres w pamięci jeżeli mam 128GB RAM?Funkcja id w pythonie ma działanie podobne do hashCode w Javie. Nawet ma podobne założenie, że jest nieunikalnym, niezmiennym identyfikatorem dla obiektu. Dla uproszczenia implementacji jeżeli obiekt jest trzymany jako struktura gdzieś niżej w C, to id zwróci adres tego obiektu. Jest to odpowiednik kodu w Javie:

koziolek@koziolek-desktop3 ~/workspace/python $ jshell
|  Welcome to JShell -- Version 11.0.13
|  For an introduction type: /help intro

jshell> System.out.println(new Integer(123).hashCode());
123

jshell> /exit
|  Goodbye
koziolek@koziolek-desktop3 ~/workspace/python $ jshell
|  Welcome to JShell -- Version 11.0.13
|  For an introduction type: /help intro

jshell> System.out.println(new Integer(123).hashCode());
123

Kolejna sprawa to pule obiektów. W celu ograniczenia zużycia pamięci można utworzyć pulę dla różnych obiektów. W Javie taka pula jest tworzona na starcie dla liczb całkowitych z zakresu od -128 do 127, co odpowiada zakresowi short i jest „good enough” w większości zastosowań. Można to zmienić za pomocą flagi -Djava.lang.Integer.IntegerCache.high=<MAX>. Drugą pulą jest pula dla String, która ma własną przestrzeń w pamięci i będzie wypełniana w czasie działania aplikacji.
W Pythonie masz coś takiego jak Small Integer Caching dla liczb z przedziału do -5 do 256. Nie ma za to przestrzeni dla puli typu String. Przy czym stringi są niezmienne więc efektywnie implementacja musi wspierać jakieś rozwiązanie pulo-podobne.

0

Ciekawostka - generowanie hashcode w HotSpot JVM (przy okazji ciekawostka dla młodszych adeptów, że Java jest napisana w C++):
https://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/87ee5ee27509/src/share/vm/runtime/synchronizer.cpp#l555
https://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/87ee5ee27509/src/share/vm/runtime/synchronizer.cpp#l601

 Possibilities:
// * MD5Digest of {obj,stwRandom}
// * CRC32 of {obj,stwRandom} or any linear-feedback shift register function.
// * A DES- or AES-style SBox[] mechanism
// * One of the Phi-based schemes, such as:
//   2654435761 = 2^32 * Phi (golden ratio)
//   HashCodeValue = ((uintptr_t(obj) >> 3) * 2654435761) ^ GVars.stwRandom ;
// * A variation of Marsaglia's shift-xor RNG scheme.
// * (obj ^ stwRandom) is appealing, but can result
//   in undesirable regularity in the hashCode values of adjacent objects
//   (objects allocated back-to-back, in particular).  This could potentially
//   result in hashtable collisions and reduced hashtable efficiency.
//   There are simple ways to "diffuse" the middle address bits over the
//   generated hashCode values:

1 użytkowników online, w tym zalogowanych: 0, gości: 1