Praca na wskaźnikach kompletnie nic nie daje. Jest to zaszłość używana w C++ do
łączenia się z niskopoziomowym kodem który wymaga pokazywania explicite miejsc w
pamięci.
Wszystkie optymalizacje które próbowałbyś robić wskaźnikami załatwia kompilator
i JIT.
--
Mateusz Ludwin mateuszl [at] gmail [dot] com
> Praca na wskaźnikach kompletnie nic nie daje.
Zrób w Javie byt, który może odnosić się do dowolnego inta w
programie.
W szczególności jeden byt powinien nadawać się do wskazywania na:
- lokalnego inta
- statycznego inta w klasie
- niestatycznego inta w klasie
- inta w tablicy
> Jest to zaszłość używana w C++
Nie zaszłość, tylko mechanizm używany do wskazywania na różne rzeczy.
To, że Java czegoś nie umie nie znaczy jeszcze, że jest to zaszłość.
W szczególności ta "zaszłość" nie jest używana tylko w C++. Mają to
chyba wszystkie języki, które są chociaż trochę bardziej kompletne i
spójne, niż Java.
> Wszystkie optymalizacje które próbowałbyś robić wskaźnikami załatwia kompilator
> i JIT.
Optymalizacje? Jeszcze do tego nie doszliśmy. Na razie jesteśmy na
etapie *w ogóle* zrobienia czegokolwiek, co spełnia powyższe
wymagania. Optymalizować (tzn. załatwiać JITem) będziemy później.
--
Maciej Sobczak * http://www.inspirel.com
Po co? Do czego to ma służyć? Takie zabawki można implementować w maszynie
wirtualnej.
>> Jest to zaszłość używana w C++
>
> Nie zaszłość, tylko mechanizm używany do wskazywania na różne rzeczy.
W takim razie wskaż zastosowania wskaźników inne niż zabawa i inne niż styk z
niskopoziomowymi bibliotekami.
> W szczególności ta "zaszłość" nie jest używana tylko w C++. Mają to
> chyba wszystkie języki, które są chociaż trochę bardziej kompletne i
> spójne, niż Java.
To java jest spójna i to was najbardziej uwiera.
>> Wszystkie optymalizacje które próbowałbyś robić wskaźnikami załatwia kompilator
>> i JIT.
>
> Optymalizacje? Jeszcze do tego nie doszliśmy. Na razie jesteśmy na
> etapie *w ogóle* zrobienia czegokolwiek, co spełnia powyższe
> wymagania. Optymalizować (tzn. załatwiać JITem) będziemy później.
"samemu zwalniać pamięć"
"nie można np. w pętli powiększać wskaźnika na znak"
Co to jest?
Funkcje niskopoziomowych bibliotek korzystają z innego menadżera pamięci niż
GC. Nie będzie problemu ze zwalnianiem nieużytków?
Siakieś implementacje interfejsu z metodą "getInt" ? W javie można to
rozwiązać obiektowo. Wystarczy zmienić kierunek myślenia ;)
> > Zrób w Javie byt, który może odnosić się do dowolnego inta w
> > programie.
> > W szczególności jeden byt powinien nadawać się do wskazywania na:
> > - lokalnego inta
> > - statycznego inta w klasie
> > - niestatycznego inta w klasie
> > - inta w tablicy
>
> Po co? Do czego to ma służyć?
No pewnie. Każdy brak w jakimś języku można tak bronić.
Kiedyś np. nie było w Javie enumów i szablonów. No bo po co?...
To ma być po to, żebym mógł sobie wskazać na inta.
> Takie zabawki można implementować w maszynie
> wirtualnej.
Nie rozumiem. Coś to pomoże na poziomie języka? Jak z tego można
skorzystać?
> W takim razie wskaż zastosowania wskaźników inne niż zabawa i inne niż styk z
> niskopoziomowymi bibliotekami.
Jak rozumiem, zabawa to jest wszystko to, czego w swojej krótkiej
karierze nie widziałeś, prawda?
Pisałeś może kiedyś jakiś serializator albo deserializator? Ja
pisałem. Kilka. W różnych językach. Zapewniam Cię, że umiejętność
swobodnego wskazywania na różne rzeczy się tam bardzo przydaje a
rzeźbienie z wrapperami czy innymi pomocniczymi mikroklasami
nieuchronnie kończy się stratą wydajności.
W ogóle od tego momentu nie rozumiem dyskusji. Referencje w Javie to
wskaźniki, więc pytanie po co są wskaźniki jest dziwne.
Język jest niespójny przez to, że te wskaźniki (co to dla zmyłki
nazywają się referencjami) nie potrafią wskazywać na wszystkie typy.
> > W szczególności ta "zaszłość" nie jest używana tylko w C++. Mają to
> > chyba wszystkie języki, które są chociaż trochę bardziej kompletne i
> > spójne, niż Java.
>
> To java jest spójna i to was najbardziej uwiera.
Vector<int> vs. Vector<Integer> - to jest spójne?
int x = new int; - Spójne?
> "nie można np. w pętli powiększać wskaźnika na znak"
>
> Co to jest?
Nie wiem, to nie ja napisałem.
> > Zrób w Javie byt, który może odnosić się do dowolnego inta w
> > programie.
> > W szczególności jeden byt powinien nadawać się do wskazywania na:
> > - lokalnego inta
> > - statycznego inta w klasie
> > - niestatycznego inta w klasie
> > - inta w tablicy
>
> Siakieś implementacje interfejsu z metodą "getInt" ? W javie można to
> rozwiązać obiektowo.
Nie chcę tego rozwiązywać "obiektowo", bo to nie jest obiektowy
problem.
If the only tool you know is a hammer...
>> Siakieś implementacje interfejsu z metodą "getInt" ? W javie można to
>> rozwiązać obiektowo.
> Nie chcę tego rozwiązywać "obiektowo", bo to nie jest obiektowy
> problem.
A niby czemu nie jest? Możesz okreslić który z twoich warunków ma niby
przekreslać użycie obiektów? W dodatku tej twój wskaźnik można sobie
wsadzić w d.. jesli doda się dodatkowo:
- inta z nie-pamieci
Co oznacza że rozwiazanie z obiektami jest "uniwersalniejsze" od głupich
wskaźników na pamięć [1].
> If the only tool you know is a hammer...
To się używa void* jak wielu programatorów w C w okolicy którzy dalej
myśla że przyspieszenie programu najlepiej zrobić pisząc wszystko w
asemblerze.
Dostałeś dokładnie odpowiedź na twoje pytanie jak to zrobić w Javie. Czy
czegoś Ci obiektowość nie rozwiązała w podanych założeniach? Są jakieś
widoczne wady tego rozwiązania wynikające z punktów które przedstawiłeś?
[1] Widziałem juz rozwiązanie problemu int-nie-z-pamięci przez wskaźnik
w C. Program dostawał wskaźnik na pamięć nielegalną. Generował wyjątek.
W wyjątku podmieniano zawartość pamięci i puszczano program dalej.
Zaiste genialne i proste. Bo obiekty Panie, to za wolne są ...
A delete vs delete [] jest spójne? Każdy język ma jakieś głupawe
konstrukcje. Ten twój Integer powstał po to żeby można bylo wlasnie miec
wskaźnik na inta. A że nie na każdego ... cóż, nie każdy int musi być w
ram i tam C też odpada.
A jak to się robi? Takie sztuczki są powszechne w systemie operaycjnym a jak
to zrobić we własnym programie? Czy przechwytując wyjątek określonego typu,
jakiego ale co potem zrobić aby kontynuować wykonywanie od miejsca
wystąpienia wyjatku?
> A jak to się robi? Takie sztuczki są powszechne w systemie operaycjnym a
> jak to zrobić we własnym programie? Czy przechwytując wyjątek
> określonego typu, jakiego ale co potem zrobić aby kontynuować
> wykonywanie od miejsca wystąpienia wyjatku?
Nie wiem jak to zrobic dzisiaj bo mnie takie hakowanie nie interesuje.
Program o którym mowie działał jeszcze w DOSie więc można było wszystko.
Nie wiem czy w ten sposób, ale może może takie techniki są wykorzystywane
dzisiaj w wirtualnych maszynach z kompilatorem JIT gdzie kompiluje się
dopiero wtedy gdy odwołujemy się do metody czy klasy jeszcze nie
skompilowanej.
> > Vector<int> vs. Vector<Integer> - to jest spójne?
>
> A delete vs delete [] jest spójne?
A co to za dziwny argument? Dyskusja nie jest o C++ ani tym bardziej o
tym, czy cokolwiek tam jest spójne. Równie dobrze mógłbyś podać
jakiś przykład z PHP i byłoby tak samo nie na temat. :-D
> Każdy język ma jakieś głupawe
> konstrukcje.
Akurat tutaj mówimy o tym, jakich konstrukcji nie ma.
> Ten twój Integer powstał po to żeby można bylo wlasnie miec
> wskaźnik na inta. A że nie na każdego ...
No właśnie.
> >>> - lokalnego inta
> >>> - statycznego inta w klasie
> >>> - niestatycznego inta w klasie
> >>> - inta w tablicy
> >> Siakieś implementacje interfejsu z metodą "getInt" ? W javie można to
> >> rozwiązać obiektowo.
> > Nie chcę tego rozwiązywać "obiektowo", bo to nie jest obiektowy
> > problem.
>
> A niby czemu nie jest? Możesz okreslić który z twoich warunków ma niby
> przekreslać użycie obiektów?
Nie trzeba przekreślać. Można wartość zmiennej przekazać mailem i też
tego nie przekreślam. Ostatecznie chodzi o naturalność rozwiązania -
przy braku wskaźników pewnych problemów (np., uwaga, problemu
*wskazywania*) nie da się naturalnie rozwiązać.
> W dodatku tej twój wskaźnik można sobie
> wsadzić w d.. jesli doda się dodatkowo:
>
> - inta z nie-pamieci
Nie spotkałem się z takim use-case'm i dlatego nie mam wymagań w tym
zakresie.
> Co oznacza że rozwiazanie z obiektami jest "uniwersalniejsze" od głupich
> wskaźników na pamięć [1].
A, o to chodzi. Tak, jest uniwersalniejsze.
Szkoda tylko, że ta uniwersalniejszość nie ma żadnej wartości dodanej,
skoro nie pokrywa żadnych wymagań.
> Dostałeś dokładnie odpowiedź na twoje pytanie jak to zrobić w Javie.
Faktycznie. Wiem już, jak samemu zrobić sobie wskaźnik.
> Czy
> czegoś Ci obiektowość nie rozwiązała w podanych założeniach?
Funkcjonalnie rzecz biorąc, jestem w pełni usatysfakcjonowany.
Niefunkcjonalnie - czytelność, błędogenność, naturalność rozwiązania,
tracking kodu do wymagań, maintainability, itd., ale kto tam dzisiaj o
takich rzeczach myśli.
> Są jakieś
> widoczne wady tego rozwiązania
Wydajność?
Niech zgadnę - załatwiamy JITem?
> [1] Widziałem juz rozwiązanie problemu int-nie-z-pamięci
Świetnie. Ale to nie mój use-case.
> Nie trzeba przekreślać. Można wartość zmiennej przekazać mailem i też
> tego nie przekreślam. Ostatecznie chodzi o naturalność rozwiązania -
> przy braku wskaźników pewnych problemów (np., uwaga, problemu
> *wskazywania*) nie da się naturalnie rozwiązać.
A rozwiązanie obiektowe jest nienaturalne? Możesz to rozwinąć? czy
naturalny jest wyłącznie asembler a cała reszta świata robi za duże
abstrakcje?
> A, o to chodzi. Tak, jest uniwersalniejsze.
> Szkoda tylko, że ta uniwersalniejszość nie ma żadnej wartości dodanej,
> skoro nie pokrywa żadnych wymagań.
Dodałeś w międzyczasie dodatkowe wymaganie "nie chcę obiektów". Poczułem
się w obowiązku dorzucić własne dla rownowagi obrazujące elastycznośc
nie używania wskaźnika. Co nie zmienia w niczym faktu że obiektowe
podejście _rozwiązuje_ problem zgodnie z życzeniem i w sposób zrozumiały
dla każdego kto zna się na obiektowości choć trochę.
>> Czy
>> czegoś Ci obiektowość nie rozwiązała w podanych założeniach?
> Funkcjonalnie rzecz biorąc, jestem w pełni usatysfakcjonowany.
> Niefunkcjonalnie - czytelność, błędogenność, naturalność rozwiązania,
> tracking kodu do wymagań, maintainability, itd., ale kto tam dzisiaj o
> takich rzeczach myśli.
Czyli uwazasz że int * jest znacznie bardziej:
a) przejrzysty (to pojedynczy int czy może cała tablica?)
b) bezpieczny (kto sledzi pamięc inta?)
c) maintability (h... wie co masz na myśli ale ... wole interfejs "int
ColorExtractor::getGrayScaleValue niż foo( int *) za 3 miesiące jak będe
oglądał na nowo kod)
?
Żartujesz sobie? stl i boost pakują whatever* do wrapperów co się tylko
da. Zapewne robia to tylko dlatego że są idiotami ktorzy nie widzą
przejrzystości i łatwości operowania int *. Nawet głupi kawałek pamięci
typu char * jest pakowany do typu interatora dla std::string. Pomyśl po co.
>> Są jakieś
>> widoczne wady tego rozwiązania
> Wydajność?
*NIE* znajdowała się ona na twojej liscie wymagań. Ponadto o wydajnosci
porozmawiamy kiedy zrobimy profiling całości aplikacji włącznie z
istniejącym po twojej stronie problemem recznego zarządzania pamięcia i
pilnowaniem walidności tych wskaźników.
Ale jest o wskaźnikach. C++ je ma i jest dobrym przykładem..
> jakiś przykład z PHP i byłoby tak samo nie na temat. :-D
PHP nie ma wskaźników jak doskonale wiesz. C++ *JEST* na temat jako
przykald twojej implementacji.
> Akurat tutaj mówimy o tym, jakich konstrukcji nie ma.
Bo gdyby je miał zarządzanie pamięcia było by znacznie bardziej
upierdliwe (zerkając na implementacje gc dla c++). Referencja na obiekt
ma mozliwość np. przemieszczania w sposób niewidoczny w pamięci w
trakcie kompaktacji heapu [1]. Ujawnienie fizycznego adresu przekresla
mozliwość wykonania takiego zabiegu i _NIC_ nie daje w zamian. *NIC*.
Jeśli jednak zaczynasz narzekać na wydajnośc to przypominam niesmiało że
narzut na referencje vs wskaźnik będzie się zapewne liniow skalował,
więc jest to mało istotny element każdego algorytmu w którym złożonosci
są często o wiele bardziej okrutne.
Więc do czego w zasadzie potrzebujesz te gołe wskaźniki w postaci adresu
w pamięci w jezyku ktory świadomie z nich zrezygonwał zyskując tym samym
ficzery nieosiągalne latwo w C++?
[1] Tak, to jest niezbedne w wielu niestandardowych wypadkach - np w
embedded bez MMU (a nawet z MMU też jest przydatne).
> >> A delete vs delete [] jest spójne?
> > A co to za dziwny argument? Dyskusja nie jest o C++
>
> Ale jest o wskaźnikach. C++ je ma i jest dobrym przykładem..
No jest - ale nadal nie wiem, o co w tej dyskucji chodzi z delete.
> > jakiś przykład z PHP i byłoby tak samo nie na temat. :-D
>
> PHP nie ma wskaźników jak doskonale wiesz. C++ *JEST* na temat jako
> przykald twojej implementacji.
Teraz rozumiem. C++ ma wskaźniki, więc jakikolwiek problem z C++ jest
dobrym argumentem w dyskusji o braku wskaźników w Javie...
> > Akurat tutaj mówimy o tym, jakich konstrukcji nie ma.
>
> Bo gdyby je miał zarządzanie pamięcia było by znacznie bardziej
> upierdliwe
Albo i nie. Ada ma wskaźniki i całkiem przyzwoite zarządzanie
pamięcią.
> Więc do czego w zasadzie potrzebujesz te gołe wskaźniki w postaci adresu
> w pamięci w jezyku ktory świadomie z nich zrezygonwał zyskując tym samym
> ficzery nieosiągalne latwo w C++?
Wskaźniki potrzebuję do wskazywania.
Wskazywanie na obiekty przydaje się w programowaniu obiektowym.
Wskazywanie na typy proste przydaje się w serializatorach.
Odpowiedź typu "a u was biją murzynów" na twój zarzut o brak spójności Javy.
> Teraz rozumiem. C++ ma wskaźniki, więc jakikolwiek problem z C++ jest
> dobrym argumentem w dyskusji o braku wskaźników w Javie...
OK. Jaki język ma bardziej pasujące wskaźniki? Tylko prosze nie
niszowo-akademicki.
> Albo i nie. Ada ma wskaźniki i całkiem przyzwoite zarządzanie
> pamięcią.
I 0% na rynku?
> Wskaźniki potrzebuję do wskazywania.
Zupelnie jak referencje + obiektowość.
> Wskazywanie na obiekty przydaje się w programowaniu obiektowym.
Zupełnie jak referencje + obiektowość.
> Wskazywanie na typy proste przydaje się w serializatorach.
Zupelnie nie wiem po co Ci typy proste [1] w serializatorach jesli masz
obiektowość. Chyba że jesteś typem człowieka który optymalizuje wynik
kompilacji na poziomie kodu maszynowego zyskując promile.
Dyskusja jest bez sensu - Java _JEST_ obiektowa i probelmy rozwiązuje
się w niej obiektowo. Co w tym dziwnego? Będziesz narzekał że języki
funkcyjne powinny pozwalać na side-effect bo Ci tego *akurat* brakuje?
Weź inny język. Brak wskaźnikow nie uniemożliwia zadania, tylko zmienia
implementację rozwiązania.
[1] Java byla by może i nawet śliczniejsza gdyby w ogóle nie było tam
typów prostych.
> A rozwiązanie obiektowe jest nienaturalne? Możesz to rozwinąć?
Rozwiązania obiektowe są naturalne tam, gdzie modelują problem ze
świata zewnętrznego (że się tak tutorialowo wyrażę). Kółko, pracownik,
ptak, samochód, te rzeczy.
Wskazywanie na inta nie jest problemem ze świata zewnętrznego, tylko
problemem technicznym, którego naturalnym rozwiązaniem jest wskaźnik
na inta.
> czy
> naturalny jest wyłącznie asembler a cała reszta świata robi za duże
> abstrakcje?
Nie pisałem o asemblerze, więc nie rozciągaj. Pisałem o wskaźniku jako
o naturalnym mechanizmie służącym do wskazywania. Użycie do
wskazywania czegokolwiek innego niż wskaźnik jest nienaturalne i nie
jest też żadną abstrakcją, tak samo jak nie jest żadną abstrakcją
używanie młotka do wkręcania śrubki.
> Dodałeś w międzyczasie dodatkowe wymaganie "nie chcę obiektów".
To nie jest wymaganie, tylko ocena rozwiązania. Rozwiązanie jest
nienaturalne, więc go nie chcę.
> Co nie zmienia w niczym faktu że obiektowe
> podejście _rozwiązuje_ problem zgodnie z życzeniem i w sposób zrozumiały
> dla każdego kto zna się na obiektowości choć trochę.
Świetny argument. Jasne, że rozwiązanie obiektowe jest zrozumiałe dla
każdego, kto zna się na obiektowości - niestety tylko na tej samej
zasadzie, jak wbijanie młotkiem śrubki jest zrozumiałe dla każdego,
kto zna się na używaniu młotka.
> Czyli uwazasz że int * jest znacznie bardziej:
>
> a) przejrzysty (to pojedynczy int czy może cała tablica?)
Pojedynczy int. Tablica powinna być osobnym typem i wymagać osobnego
typu wskaźnika.
(hint: to, że w C++ jest to spieprzone nie znaczy jeszcze, że
koncepcja wskaźnika jest zła, bo są języki, gdzie jest to zrobione
dobrze)
> b) bezpieczny (kto sledzi pamięc inta?)
int * jest tak samo bezpieczny jak dowolna referencja w Javie.
Niebezpieczne mogą być co najwyżej niesprawdzane konwersje wskażników.
> c) maintability (h... wie co masz na myśli ale ... wole interfejs "int
> ColorExtractor::getGrayScaleValue niż foo( int *) za 3 miesiące jak będe
> oglądał na nowo kod)
Znowu argument nie na temat, bo posłużyłeś się różnymi nazwami funkcji
i to z różnych zakresów widoczności. To jest dobry argument, ale na
inną dyskusję - na pewno nie udowodnisz w ten sposób tezy, że
wskaźniki są złe.
> Żartujesz sobie? stl i boost pakują whatever* do wrapperów co się tylko
> da. Zapewne robia to tylko dlatego że są idiotami ktorzy nie widzą
> przejrzystości i łatwości operowania int *. Nawet głupi kawałek pamięci
> typu char * jest pakowany do typu interatora dla std::string. Pomyśl po co.
Ja wiem po co. Nie zmienia to faktu, że te wszystkie rzeczy używają w
swojej implementacji wskaźników a nie obiektów. Teraz Ty pomyśl, po
co.
Znowu posługujesz się złym argumentem, bo odwołujesz się do
enkapsulacji, która znowu nie ma związku z tematem. Przecież ja nie
twierdzę, że enkapsulacji nie należy robić.
W szczególności mój przykładowy serializator w ogóle nie posługuje się
wskaźnikami w swoim interfejsie publicznym. Posługuje się nimi
wyłącznie w swojej prywatnej implementacji - i to jest właśnie coś, co
można zrobić *naturalnie* w C++ (i w dowolnym innym kompletnym języku)
a czego nie można zrobić w Javie.
> > Wydajność?
>
> *NIE* znajdowała się ona na twojej liscie wymagań.
Faktycznie.
> Ponadto o wydajnosci
> porozmawiamy kiedy zrobimy profiling całości aplikacji włącznie z
> istniejącym po twojej stronie problemem recznego zarządzania pamięcia i
> pilnowaniem walidności tych wskaźników.
Tak, to dobry pomysł.
Proponuję np. to, żeby nie było, że sam coś spreparowałem:
http://zeroc.com/articles/IcePerformanceWhitePaper.pdf
To jest artykuł porównujący wydajność pewnego systemu middleware (ICE)
w różnych implementacjach - w szczególności dla C++ i Javy. Zakładamy,
że panowie napisali jedno i drugie najlepiej jak umieli. Obie
implementacje pochodzą z tej samej firmy, więc zakładamy też, że wybór
architektury i algorytmów jest podobny, czyli faktycznie jest to
porównanie wydajności języków a nie np. sortowania bąbelkowego w Javie
z quick-sortem w C++.
(middleware to w ogóle świetny temat do porównań, bo jest to chyba
jedyna działka w IT, gdzie pisze się naprawdę to samo w kilku językach
- *tylko* wtedy jakiekolwiek porównania języków mają sens)
Otóż we *wszystkich* tabelkach w tym artykule, niezależnie czy chodzi
o latency czy o throughput, Java systematycznie wypada gorzej. Testów
jest bardzo dużo, więc raczej nie chodzi o przypadek.
A teraz uważaj: *wszystkie* znane mi systemy middleware, które
istnieją w kilku językach, mają dokładnie tak samo. Ciekawe, prawda?
Odnosząc się do Twoich nietrafionych argumentów ze wskaźnikami - w ICE
gołe wskaźniki w ogóle nie są używane w interfejsie publicznym.
Natomiast są używane w implementacji.
I o to właśnie chodzi. Obiektowość niech sobie będzie tam, gdzie jest
naturalna - a tam gdzie jest nienaturalna, niech się nie narzuca. To
jest ten drobiazg, który odróżnia C++ od Javy - i jednocześnie ten,
który wpływa potem na liczby w tabelkach.
Pozdrawiam tych, którzy wierzą w cudowne zdolności JITa w przywracaniu
wydajności tam, gdzie została ona pogrzebana użyciem nienaturalnych
technik programistycznych.
Iterator, kolejka haszująca i inne problemy świata zewnętrznego ...
> Wskazywanie na inta nie jest problemem ze świata zewnętrznego, tylko
> problemem technicznym, którego naturalnym rozwiązaniem jest wskaźnik
> na inta.
Nie jest *naturalnym* tylko jednym z wielu. W dodatku jesli posiadasz gc
to przeszkadzającym w gładkiej implemetacji dodatkowych ficzerów w
języku wyciągając elementy impelementacji poza VM. Ciekawostka: co
zrobisz jesli masz system embedded z 64kB RAM bez MMU i dużo "swapu" na
flash (przypadek z mojego biurka)? W przypadku Javy to gdzie jest obiekt
(w ram czy swap) i jak się do niego dostać jest komplenie odizolowane od
problemu implementacji algorytmu. W C++ wyciąga się to wprost w sam
środek algorytmu. W takich systemach gdzie kompaktowanie pamięci ma
*krytyczne* znaczenie C++ tylko przeszkadza. Abstrakcja na pamięć
generuje spowolnienia, ale pozwala aplikacji w ogole dzialać. To kwestia
stwierdzenia gdzie są priorytety.
Jeśli potrzebujesz wydajności nie bierzesz Javy. To raczej oczywiste.
Jesli potrzebujesz wskaźnikow bierzesz C++/whatever. Ale twoje zadanie
jest rozwiązywalne w obu językach z identyczna funkcjonalnością
(pomiajam prędkośc, jako że java ogólnie jest upierdliwie powolna) choć
innymi metodami.
> Użycie do
> wskazywania czegokolwiek innego niż wskaźnik jest nienaturalne
Zapytam inaczej: *PO* *CO* jeszcze chcesz wskazywać zamiast mieś
referencję gdyby nie problem wydajności? W gruncie rzeczy to jest to
samo za wyjątkiem tego że wskaźnik wyciąga bebechy pamięci na światło
dzienne i pozwala na wskazywanie na nieobiektowe konstrukcje (w C++) co
można owrapować w obiekt. Sa jakies cechy lepszości wskaźnikow nad
referencję na interfej gettera/settera (przypominam: pomijając wydajność)?
>> Dodałeś w międzyczasie dodatkowe wymaganie "nie chcę obiektów".
> To nie jest wymaganie, tylko ocena rozwiązania. Rozwiązanie jest
> nienaturalne, więc go nie chcę.
Obawiam się że Java po prostu jest w twoim wypadku problemem gustu a nie
merytorycznych przeszkód niemożnosci implementacji czegoś.
>> Czyli uwazasz że int * jest znacznie bardziej:
>> a) przejrzysty (to pojedynczy int czy może cała tablica?)
> Pojedynczy int. Tablica powinna być osobnym typem i wymagać osobnego
> typu wskaźnika.
Zupełnie jak sugerowany przez mnie intefejs. Dla tablicy będzie innym
typem niz dla pojedyńczego inta.
> int * jest tak samo bezpieczny jak dowolna referencja w Javie.
"Szczególnie" w wiodącym języku ze wskaźnikami. Wiem, bo piszę sporo i w
dużym kodzie.
> Ja wiem po co. Nie zmienia to faktu, że te wszystkie rzeczy używają w
> swojej implementacji wskaźników a nie obiektów. Teraz Ty pomyśl, po
> co.
*NIC* nie to nie obchodzi, bo po stronie mojej ten wskaźnik jest
nierozróżnialny od wrappera. Do tego stopnia że w wersji debug wskaźniki
magicznie zamieniają się na inteligentne wrappery na nie. Wrapowanie
bebechów języka w obiekty pozwala na magiczne sztuczki ktore normalnie
musiałbyś dziargać samodzielnie psując wygląda kodu.
Zauwazyleś że bardzo dużo rzeczy w boost jest kopiowanych? To zachęcia
do robienia wrapperów jak chociażby shared_ptr ktore de facto robią z
pointera referencję javową.
> wyłącznie w swojej prywatnej implementacji - i to jest właśnie coś, co
> można zrobić *naturalnie* w C++ (i w dowolnym innym kompletnym języku)
> a czego nie można zrobić w Javie.
Dla Javy naturalne sa obiekty. Więc jest to rozwiazanie *naturalne* w
Javie. Co ciekawe - w zupełności wyczerpujace temat Twojego zadania. Co
oznacza że dodatkowy zbedny element języka jest ... zbędny.
> Otóż we *wszystkich* tabelkach w tym artykule, niezależnie czy chodzi
> o latency czy o throughput, Java systematycznie wypada gorzej. Testów
> jest bardzo dużo, więc raczej nie chodzi o przypadek.
Czy przyznaje ze nie mam teraz czu czytać. Ktos pokusił się na odpowiedź
na pytanie co jest problemem? Java nalezy do języków ogolnie z duzym
narzutem. Magiczne dodanie wskaźnika niczego nie poprawi, spowolnienia
sa cechą samej budowy VM i jezyka, jest mocno nieuczciwe porównywanie
nierównych z definicji językow w celu dyskucji o potrzebie dorzucenia
wskaźnika do Javy.
> Odnosząc się do Twoich nietrafionych argumentów ze wskaźnikami
Ktorych *nietrafnych*? Że C++ nie jest szybszy? A gdzie ja tak twierdze?
Śmiem twierdzić że narzut na obiektowość vs wskaźniki jest liniowy a to
oznacza że nie jest tak krytyczny jak wyższa złożoność.
> Pozdrawiam tych, którzy wierzą w cudowne zdolności JITa w przywracaniu
> wydajności tam, gdzie została ona pogrzebana użyciem nienaturalnych
> technik programistycznych.
Całe szczęście że ja piszę w C++ (ze wskaźnikami) na codzień i świadomie
nie wciskam ich do Javy bo to *inny* jezyk. Więc jestem ostatnim który
daje wiarę w magiczną szybkość Javy.
Proponuję nie mieszać pojęć i odróżnić programowanie obiektowe
od programowania przy użyciu obiektów.
> Będziesz narzekał że języki
> funkcyjne powinny pozwalać na side-effect bo Ci tego *akurat* brakuje?
Pozwalają. np Ocaml, F#.
Pozdrawiam
KK
Zakładając nie mieszanie tych pojęć - co to niby zmienia? Java
udostepnia wszystko przez obiekty. To właściwa forma rozwiązywania
wszelkich problemów. To podstawa tego języka. I nie ogranicza go
funkcjonalnie, jedynie zmienia sposób implementacji w stosunku do innej
mozliwej z C++. To próbuje udowodnić.
>> Będziesz narzekał że języki
>> funkcyjne powinny pozwalać na side-effect bo Ci tego *akurat* brakuje?
> Pozwalają. np Ocaml, F#.
Złosliwi twierdzą że to nie są jezyki funkcyjne wlaśnie dlatego.
To *jedyna* forma rozwiązywania problemów. Dlatego używa się tam
obiektów np. do implementacji tablicy mieszającej, ale z programowaniem
obiektowym nie ma to nic wspólnego.
> To podstawa tego języka. I nie ogranicza go
> funkcjonalnie, jedynie zmienia sposób implementacji w stosunku do innej
> mozliwej z C++. To próbuje udowodnić.
Ogranicza. Jak sam zauważyłeś wprowadza narzut na pamięć i wydajność.
W Javie przydały by się struktury, które mogły by być przekazywany
przez wartość i porządne generyki. O ile w pierwszym przypadku
można je bez problemu dodać, w drugim jest już pozamiatane - co nie
znaczy, że nie próbuje się tego rozwiązać:
http://www.scala-lang.org/sites/default/files/sids/dragos/Thu,%202010-05-06,%2017:56/sid-spec.pdf
>>> Będziesz narzekał że języki
>>> funkcyjne powinny pozwalać na side-effect bo Ci tego *akurat* brakuje?
>
>> Pozwalają. np Ocaml, F#.
>
> Złosliwi twierdzą że to nie są jezyki funkcyjne wlaśnie dlatego.
Złośliwym pewnie chodziło o to, że nie są to języki czysto funkcyjne
( bo nie są, to fakt, a nie złośliwość ).
Pozdrawiam
KK
Oczywiście chodzi o ograniczenia Java VM. W Scali jest to jakoś
rozwiązane, w Javie jak chcesz, aby było wydajnie weź plik
z implementacją i zrób zastąp w ulubionym edytorze :).
Pozdrawiam
KK
Jakie możliwości miałby mieć wskaźnik na inta. Aby było bezpiecznie mogłoby
działać przypiasanie do int* czyli takie same możliwości jak referencja,
natomiast nie mozna by modyfikować samego wskaźnika, bo na co wskzywałby
wskaźnik+1 ?
> To *jedyna* forma rozwiązywania problemów.
Podobnie jak nie-obiektowośc i wskaźniki sa jedyna formą rozwiązywania
problemów w C/asm. To cecha jezyka. Niektórzy nie moga jednak bez
obiektowości żyć więc zamiast wziąść lepszy język emuluja obiektowość na
wskaźnikach i strukturach w C klnąc przy tym jakie to badziewie.
> Ogranicza. Jak sam zauważyłeś wprowadza narzut na pamięć i wydajność.
Przecież nie tylko brak wskaźników wprowadza te narzuty. Ten język
został w solidny sposób ograniczony przy projektowaniu, teraz wszyscy
starają się go nadmuchać krzycząc że sie nie da. No nie da sie, powstały
inne, ewolucja. Popularnośc pokazuje ze te ficzery niekoniecznie są
niezbędne.
> W Javie przydały by się struktury, które mogły by być przekazywany
> przez wartość i porządne generyki.
"Przydaly by się" != "są niezbędne".
Mi by się cholernie przydaly typy unsigned.
Jest cała masa rzeczy które by się przydały w różnych językach. Jeśli
ich bak uniemożliwia rozwiązanie problemu to mamy brak powazny. A tu nie
- mimo "braków" zalożenie zostało spełnione o dostępie "prawie jak przez
wskaźnik" i wszyscy poza wydajnością moga sie cieszyć.
Na marginesie:
Powtarzam: w ogóle mnie nie interesuje wydajnośc Javy. To jest język
który ma inne cechy dla których go sporadycznie stosuje. Jednak nie
potrafie zrozumiec dlaczego abstrakcje na pamięć miałbym zastapić
mechanizmem zapozyczonym z innego jezyka tylko dlatego że komuś się nie
podoba taka czy inna forma rozwiązywania problemu. Abstrakcyjna pamięć w
javie pozwala zrobić rzeczy nieosiągalne w C++ w posob prosty.
> > Teraz rozumiem. C++ ma wskaźniki, więc jakikolwiek problem z C++ jest
> > dobrym argumentem w dyskusji o braku wskaźników w Javie...
>
> OK. Jaki język ma bardziej pasujące wskaźniki? Tylko prosze nie
> niszowo-akademicki.
Dlaczego nie? To, czy coś jest dobre czy złe nie ma związku z tym, czy
jest niszowe.
(złośliwi twierdzą, że jednak ma związek, ale właśnie odwrotny)
Czyli znowu sięgasz po argumenty nie na temat.
> > Albo i nie. Ada ma wskaźniki i całkiem przyzwoite zarządzanie
> > pamięcią.
>
> I 0% na rynku?
Znowu argument nie na temat.
> Zupelnie nie wiem po co Ci typy proste
Świetny punkt. Ale to nie ja wsadziłem te typy do Javy. Skoro już tam
są i są powszechnie używane, to niech będą też kompletnie wspierane.
> [1] Java byla by może i nawet śliczniejsza gdyby w ogóle nie było tam
> typów prostych.
Nie mam nic przeciwko takim rozwiązaniom [*]. Oczekuję tylko, że:
- albo język ma typy proste z kompletnym i spójnym wsparciem
- albo ich wcale nie ma i wtedy jest spójny przez fakt, że ma tylko
typy obiektowe
Naprawdę byłbym zadowolony z obu rozwiązań.
Nie jestem natomiast zadowolony z rozwiązania z Javy, gdzie typy
proste są, ale nie są wspierane przez resztę języka. To jest po prostu
sieczka.
[*] Z drobnym wyjątkiem - w historii był już taki język i zniknął.
Tak, wiem, argument nie na temat, ale jeśli sam się takim argumentem
posługujesz, to być może dojdziesz do wniosku, że jednak typy proste
są do czegoś w języku potrzebne.
> Ciekawostka: co
> zrobisz jesli masz system embedded z 64kB RAM bez MMU i dużo "swapu" na
> flash (przypadek z mojego biurka)?
Zrobię to przez abstrakcję. Tak, jak w Javie.
Ten problem nie jest prostym problemem wskazywania inta, tylko
problemem abstrakcyjnego źródła danych.
> W C++ wyciąga się to wprost w sam
> środek algorytmu.
Nie ma takiego obowiązku. W C++ *można* pisać obiektowo.
> To kwestia
> stwierdzenia gdzie są priorytety.
Bingo. Teraz inna ciekawostka: nie masz problemu z pamięcią, natomiast
masz problem z wydajnością. Jak sam napisałeś: to kwestia stwierdzenia
gdzie są prioritety.
Różnica między C++ i Javą jest taka, że w C++ priorytety ustala
programista a w Javie już są ustalone.
> Jeśli potrzebujesz wydajności nie bierzesz Javy. To raczej oczywiste.
To o czym dyskutujemy?
> > Użycie do
> > wskazywania czegokolwiek innego niż wskaźnik jest nienaturalne
>
> Zapytam inaczej: *PO* *CO* jeszcze chcesz wskazywać zamiast mieś
> referencję gdyby nie problem wydajności?
Gdyby nie problem wydajności to świat wyglądałby inaczej, ale to
stwierdzenie jest mało konstruktywne.
Pewien guru od systemów embedded powiedział, że gdyby nie problem
kosztów, to w ogóle nie byłoby sensu pisać programów, bo wszystko
mozna zrobić bezpośrednio w sprzęcie. To też prawda, ale podobnie mało
konstruktywna.
> Obawiam się że Java po prostu jest w twoim wypadku problemem gustu a nie
> merytorycznych przeszkód niemożnosci implementacji czegoś.
Błąd. Ja chcę mieć naturalne rozwiązania technicznych problemów
implementacyjnych. Te problemy są różne zależnie od celu, ale jeżeli
celem jest wydajność, to problemy są takie a nie inne i wtedy
naturalne rozwiązania też są takie a nie inne. To nie jest kwestia
gustu.
> Dla Javy naturalne sa obiekty. Więc jest to rozwiazanie *naturalne* w
> Javie. Co ciekawe - w zupełności wyczerpujace temat Twojego zadania. Co
> oznacza że dodatkowy zbedny element języka jest ... zbędny.
Błąd. W ten sam sposób można uzasadnić kompletność asemblera czy w
ogóle maszyny Turinga.
Zastanów się nad tym:
W maszynie Turinga jest taśma, po której się jeździ w prawo i w lewo.
Wniosek: rozwiązania, które jeżdżą po taśmie w prawo i w lewo są
naturalnym rozwiązaniem jakiegokolwiek problemu w maszynie Turinga.
To jest błąd w procesie myślowym. Tak się nie da niczego udowodnić.
Albo inaczej: język (czy w ogóle jakakolwiek technologia) nie jest
celem, tylko narzędziem. Jeżeli to narzędzie jest nienaturalne w
jakimś problemie, to bierzemy inne narzędzie a nie mędrkujemy, że
walenie młotkiem w śrubkę jest naturalnym rozwiązaniem problemu śrubki
przy zastosowaniu młotka. Tego typu rozumowanie jest po prostu głupie.
> Czy przyznaje ze nie mam teraz czu czytać. Ktos pokusił się na odpowiedź
> na pytanie co jest problemem? Java nalezy do języków ogolnie z duzym
> narzutem. Magiczne dodanie wskaźnika niczego nie poprawi, spowolnienia
> sa cechą samej budowy VM i jezyka, jest mocno nieuczciwe porównywanie
> nierównych z definicji językow w celu dyskucji o potrzebie dorzucenia
> wskaźnika do Javy.
Ale właśnie brak wskaźników w Javie jest związany z wyborem VM jako
platformy wykonawczej. To jest trade-off.
Wszystko jest OK, jeśli uznamy ten trade-off i jeśli jesteśmy jego
świadomi.
Gorzej, jak na skutek wyboru VM jako jedynej słusznej metody
wykonywania programów dochodzimy do wniosku, że wskaźniki są
zaszłością albo że są niepotrzebne. To właśnie ten wniosek jest
skrajnie głupi i to właśnie on spowodował rozwinięcie tej dyskusji.
Ja tu nie neguję potrzeby istnienia wielu różnych technologii. Neguję
zaślepienie, któro udziela się niektórym ludziom na skutek wyboru
jednego tylko rozwiązania.
> Naprawdę byłbym zadowolony z obu rozwiązań.
> Nie jestem natomiast zadowolony z rozwiązania z Javy, gdzie typy
> proste są, ale nie są wspierane przez resztę języka. To jest po prostu
> sieczka.
Dla kogos nowego w javie, jest to moze i sieczka i stwarza problemy, ale
dla kogos kto napisal juz troche linii kodu, staje sie to naturalne.
Teoretycznie od czasu wprowadzenia autoboxingu mozemy zapomniec o
problemie, chociaz i tak trzeba miec to na uwadze, aby nie pisac kodu ktory
ciagle boxuje i unboxuje wartosci bo bedzie mialo to negatywny wplyw na
wydajnosc.
Stan ten naprawiono w Groovym, gdzie wszystkie type sa "klasowe", lub tak
jak w scali, gdzie jest to z poziomu jezyka ukryte, mamy tylko jeden typ,
ale wewnetrzna implemetnacja wykorzustuje albo tym prosty albo klasowy
automatycznie w zaleznosci od zastosowania...
Pozdrawiam
Brzezi