Google Go czyli trochę lepsze C
- Dodano: 11 listopada 2009
- Wprowadził: michuk
- Komentarze: 128
Google pokazał światu nowy język programowania. „Go” ma być tak szybkie jak C/C++, ale przyjemniejsze dla programisty dzięki zastosowaniu technik znanych z języków wyższego poziomu (jak Java czy Python). Licencja języka to BSD.
Nie spodziewajcie się rewolucji. Go nie zaskoczy Was tak jak kiedyś Haskell, Erlang, czy — w ostatnim czasie — Scala. Nowość od Google to zwykły obiektowy język niskopoziomowy składnią bardziej przypominający C. Chodzi o to, żeby nie „alienować” deweloperów. Takie podejście sugeruje, że Google liczy na masową adopcję swojego nowego dziecka.
Kto tworzy Go?
Go został stworzony w dodatkowym czasie (słynne googlowskie 20% czasu, które każdy programista może przeznaczyć na dowolny projekt). Od dwóch lat rozwijany jest już jednak jako pełnoprawny projekt Google, a o jego wadze świadczy zespół programistów, jaki pracuje nad Go. Są to m.in.:
- Kenneth Thompson — współtwórca UNIX-a i języka B (który został następnie przeprojektowany przez Dennisa Ritchie jako C),
- Rob Pike — twórca systemu operacyjnego Plan 9 oraz systemu kodowania UTF-8,
- Robert Griesemer — wcześniej zaangażowany w prace nad kompilatorem Java HotSpot oraz V8, silnik javascriptowy przeglądarki Chrome
Czym więc różni się Go od C?
Według twórców, główne jego zalety Go w stosunku do C to:
- Ułatwienie programistom w pisaniu kodu na wiele rdzeni poprzez zastosowanie specjalnych konstrukcji („goroutines”) oznaczających konieczność wykonania danego kodu współbieżnie. Funkcje takie prefiksujemy po prostu napisem „go”, dzięki czemu wykonywane będą one w oddzielnych „kanałach”. Kanały te umożliwiają bezpieczne (thread-safe) przekazywanie danych w obie strony.
- Nowy model tworzenia interfejsów — definiujemy je podobnie jak w Javie, ale nie musimy explicite specyfikować która klasa implementuje dany interfejs. Daje to elastyczność podobną do duck-typing, jednak zachowujac statyczne typowanie.
- Konstrukcje językowe wzięte wprost z Pythona jak słowniki czy „array slices” ułatwiające pisanie zrozumiałego kodu.
- Garbage collector
A oto przykład prostego kodu w Go:
1. func sum(a []int) int { // returns an int
2. s := 0;
3. for i := 0; i < len(a); i++ {
4. s += a[i]
5. }
6. return s
7. }
8.
9. s := sum(&[3]int{1,2,3}); // a slice of the array is passed to sum
Obecnie język jest podobno 20-30% wolniejszy od C, co można uznać za bardzo dobry wynik. W wyniku dalszej optymalizacji różnica ta powinna stać się jeszcze mniejsza.
Do czego służy Go?
Go ma być językiem dowolnego zastosowania, ale sami twócy zdradzają, że najbardziej przydać się on może do tworzenia oprogramowania serwerowego, wymagającego wysokiej efektywności, jak serwery webowe czy serwery aplikacji.
Co ciekawe, Pike wspomina jednak również o zupełnie innym zastosowaniu. Uważa on, że Go mógłbyu być dobrym… następcą JavaScriptu, gdyż „jest co najmniej o rząd wielkości lepszy od JS”. Pytanie tylko — co nie jest
Jeśli chcielibyście zapoznać się z nowym językiem Google, przydatna będzie na pewno oficjalna strona języka Go na której znajdziecie mnóstwo przykładów oraz ściągniecie kompilator. Niestety nie ma jeszcze wielu bibliotek, w powijakach jest też integracja z IDE. Jeśli pojawi się zainteresowanie deweloperów, braki te zostaną zapewne szybko uzupełnione.
Więcej informacji: http://arstechnica.com/open-source/news/...mpaign=rss
Znalazłeś literówkę? Zgłoś ją używając formularza!
Jeśli uważasz, że ten nius jest nieobiektywny, przedstawia nieprawdziwe wydarzenie, jest spamem lub nie spełnia standardów serwisu, napisz raport.
Niusy na podobny temat:
Komentarze są prywatnymi opiniami dodających je osób. Prosimy o zachowanie kultury wypowiedzi. Komentarze obraźliwe oraz obniżające poziom serwisu będą usuwane. Więcej w regulaminie komentowania.
128 komentarzy
Wszystkie autorskie niusy w serwisie publikowane są na licencji Creative Commons Uznanie autorstwa 2.5 Polska.


To mi wygląda na najdonioślejszy nius z dziedziny języków programowania od czasu, kiedy Microsoft zaproponował C#. Ciekawe, czy można w łatwy sposób używać procedur stworzonych w języku C (na C++ nie liczę)?
Najdonioślejszy? O języku D nie słyszałeś? IMO lepszy od Go.
Chodzi o język z Digital Mars? Tak, i też uważam, że jest ciekawym wynalazkiem, ALE Go jest technologią która – choćby ze względu na reputację stojących za nią osób, ale także ze względu na realne możliwości i rzeczywiście liberalną licencję – ma szansę solidnie na rynku zamieszać, co – jak już można stwierdzić – nie udało się niestety językowi D.
Dodaj do tego explicite wsparcie dla równoległości obliczeń (jest kwestią najbliższych lat, kiedy mainstreamowe mikroprocesory będą miały dziesiątki rdzeni i hardware transactional memory, zaś tradycyjne sposoby programowania będą jeszcze bardziej nieporęczne niż dzisiaj) w ogólnodostępnej platformie programistycznej może być kolejnym potężnym magnesem przyciągającym autorów aplikacji do tego języka.
Jak dla mnie, Google mógłby dogadać się najpierw z Nvidią, AMD i Intelem (producentami kart graficznych) zanim by wypuścił Go. Chodzi o to, że każda z tych firm (może z wyjątkiem Intela) tworzy własny język do programowania multicore'ów. Co najmniej kilka lat zamieszania…
Bez przesady. OpenCL chyba to zamieszanie nieco umniejsza.
Go za to nie jest tylko do "programowania multicorów", a tworzenia aplikacji ogólnego użytku, ze szczególną preferencją na komunikację.
Jakoś trudno jednak go zaklasyfikować – nie wiadomo gdzie jego miejsce wśród Pythona, C, Erlanga, Javy. Chyba może stanowić dobrą alternatywę dla tych dwóch ostatnich, szczególnie w zastosowaniach, za przeproszeniem, biznesowych.
Bosze.. jak za tym wszystkim nadążyć!!! Jeszcze C99 nie zdążył się zadomowić a już wymyślają kolejną protezę.
Ale dobra… będzie wolna chwila to łykniemy też i to jak będzie warto.
Jedno tylko pytanko – jak "GO" jako język kompilowany zamierza zastapic JavaScript, który jest wykonywany po stronie klienta? Czyzby najpierw przeglądarka ściągała kompilator (podobnie jak pierwsze ściągnięcie wtyczki do Flash), aby potem kompilować skrypty GO umieszczone na stronie? A może wymyślili to jako jezyk, który można interpretować ale i komplilowac, zalezy co mamy pod ręką. Tylko dlaczego nie wymyslili czegos takiego dla Javy, która jest jezykiem kompilowanym i jest jej na pewno bliżej do JavaScript.
Spieszę wyjaśnić, że technologia języka Go jest objęta liberalną licencją BSD, a więc możliwe jest włączenie stosownego kompilatora wprost do dowolnej popularnej przeglądarki i kompilacja "w locie" : jako że nie jest to C++ wyposażony w templates, boost::mpl:: i inne boost::lambdy::, to jego kompilowanie będzie trwało ułamek sekundy a nie 7 lat
No jasne, ze ułamek sekundy… nie wyobrażam sobie raczej w tej chwili załączania do strony źródeł GO, które miałby funkcjonalność MS Worda czy Adobe PhotoShopa.
Ale może właśnie to przyświeca twórcom – aplikacje webowe wykonywane tak naprawdę po stronie klienta. Czyli… chcesz Worda (albo odpowiednik) – zapłać, wejdź na stronę (ona ściągnie ci źródła i je skompiluje) i używaj. Program będzie działać dopóki możesz się na stronie zalogować, ale tak naprawdę będzie on działać na twoim kompie.
Czyli my mamy kasę, ale obciążony jest twój komp, a nie nasz serwer.
Sprytne i całkiem logiczne.
I jakież szerokie możliwości kontrolowania użytkownika. Program jest na twoim kompie, ale tak naprawdę to my kontrolujemy kiedy go możesz użyć. Opłata roczna? Proszę bardzo. Opłata miesięczna, dzienna albo jednorazowa? Czemu nie?
To może być przyszłość wielu aplikacji.
Spieszę wyjaśnić, że typowa aplikacja AJAXowa obciąża zasoby peceta klienckiego BARDZIEJ niż odpowiadająca jej funkcjonalnie aplikacja "zwykła", a to w szczególności ze względu na zasobożerność przeglądarki webowej, a po drugie ze względu takiego, iż typowa aplikacja AJAXowa nie releguje obliczeń na serwer, gdyż często powodowałoby to nieakceptowalne opóźnienia, a jedynie przenosi na stronę serwera samo składowanie danych i dostarczanie aplikacji, zaś obie te rzeczy (a w szczególności tą pierwszą) można równie dobrze osiągnąć bez pomocy AJAXu. Co więcej: aplikacje webowe (tak, już dzisiaj prawie wszystkie wykonywane tak na prawdę po stronie klienta, przynajmniej w dużej części) się twórcom opłacają, bo z taką aplikacją do klienta łatwiej dotrzeć: klient aplikację może po prostu używać bez świadomości pobierania i instalowania czegokolwiek
ehh garbage collector, znowu leczenie objawowe.
brak przeciazania i dziedziczenia typow…
gofunkcje to po prostu asynchroniczne funkcje, nie udostepniaja mechanizmow wspomagajacych synchronizacje itp. szkoda..
( once.Do() zaimplementuje w pol godziny srednio rozgarniety student)
go moze byc ciekawa alternatywa dla programistow C, ale nie wydaje mi sie aby wzbudzil duze zainteresowanie w srodowisku C++
(chociaz tu moze przemawiac moje przywiazanie do C++
Co widzisz zdrożnego w garbage collectorze?
Niemożność zrobienia RAII. GC przydaje się tylko do pamięci. Do plików, połączeń do baz danych, gniazdek, muteksów itp. już nie (do muteksów to bardzo nie
).
Dlatego dobre GC to GC które można włączyć wybiórczo dla poszczególnych obiektów (ew. wyłączyć).
W dodatku zupełnie się nie sprawdza tam gdzie mamy do dyspozycji mało pamięci, ot choćby takie Cell-owe SPU.
Mimo, że generalnie podoba mi się ten język i jego konstrukcja, to jednak raczej C-killer to nie będzie.
Narzut pamięciowy na GC, szczególnie kompaktujący nie jest specjalnie duży. Inna sprawa, że jest.
I wymaga asynchronicznego nadzoru, a nie zawsze możesz sobie na to pozwolić bez wyraźnej straty wydajności (tu znowu przytoczę przykład jednostki SPU, której przerwanie pracy naprawdę jest kosztowne).
@bies w praktyce GC można sobie "prawie" wyłączyć wpisując null-e do referencji w obiektach, a na pewno ułatwić pracę GC. A zdecydowanie warto usuwać dwustronne powiązania pomiędzy obiektami.
Implementowałem kiedyś prosty GC dla C++ i to co, zajmuje naprawdę czas w GC to jest sprawdzanie wzajemnych odwołań do obiektów, w celu określenia czy grupa obiektów odwołujących się nawzajem jest adresowana przez program (czy istnieje wykorzystywana referencja w programie, która wskazuje na dowolny obiekt z grupy).
Teoretycznie, problem asynchronicznej pracy GC można by jeszcze rozwiązać przez wywoływanie go przy każdej nowej alokacji, ale boję się, że to było by jeszcze "cięższe" rozwiązanie niezależnie od implementacji samego GC.
Może troszke off-topic ale wydaje mi się, z teorii, że idzie się do wszystkich obiektów do których można dotrzeć poczynając od obieków na stercie ( takie przejście po drzewie) i zanacza je się jako “nie do usuniecia” pozostałe ( te do których się niedotarło ) GC wywala . Nie ma wtedy problemu „wzajemnych referencji”
Narzut pamięciowy na dobre GC jest nie większy niż narzut pamięciowy przy ręcznej alokacji. Ręczna alokacja też marnuje RAM, tylko w inny sposób.
GC marnuje RAM, bo nie zwalnia zasobów od razu. Ręczna alokacja marnuje RAM na fragmentację sterty. Oba zjawiska mają podobną skalę (zwiększenie zużycia pamięci o ok. 50%), z tą różnicą, że w przypadku GC ma się nad tym kontrolę.
Inna sprawa, że GC użytemu w Go bardzo daleko do GC Javy czy C#. "30%" wolniejszy niż C, to chyba porównywali do nieoptymalizowanego C. Klasyczny, niegeneracyjny Mark & Sweep GC zmarnuje 30% CPU jak się ma szczęście. Java jest średnio w różnych testach ok. 10-40% wolniejsza niż dobrze zoptymalizowane C, a ma dużo bardziej zaawansowany runtime niż Go.
Co do RAII, to w językach wysokiego poziomu ten hack nie jest potrzebny ani użyteczny, bo język ma zwykle wsparcie explicite dla zarządzania zasobami innymi niż pamięć. Np. poprzez "automatic resource management blocks".
Dna: prawie to niestety za mało w przypadku zasobów rzadkich. W przypadku muteksów prawie to dramat. Dlatego, trzeba albo ręcznie zwalniać muteks — co jest błędnogenne, albo wrzucić synchronizację do języka (np. synchronized w Javie).
@Królik: GC działa _and_ warstwą ręcznej alokacji w systemie czyli na istniejący narzut dodaje jeszcze swój. Odkąd mamy mamy procesory wspierające sprzętowo segmentację pamięci ciągłość obszaru wirtualnego nie ma przełożenia na ciągłość i porządek w przestrzeni fizycznej.
Królik: ARM to jest RAII zrobiony w Javovy sposób. Należy tylko uśmiechnąć się i powiedzieć ,,nareszcie'' (albo zapłakać będąc zagrzebanym w SAP-ie i jdk1.4).
A w ogóle to w końcu weszło to Javy7? Czy nadal jest jako propozycja (nie śledzę 7 — dla mnie to dopiero za circa 5 lat)?
A fragmentacji można uniknąć (alokatory, areny). Oczywiście kompaktujący GC ma fajnie. Od jakiegoś czasu chodzi mi kompaktujący GC dla C++ na zasadzie dodatkowej adresacji pamięci. Ale nie mam czasu aby spróbować zrealizować.
@wojtekm: GC nie działa NAD warstwą ręcznej alokacji, tylko ZAMIAST niej, przynajmniej w przypadku szanujących się platform jak .NET czy Java. W obu przypadkach alokatory uzyskują pamięć całymi blokami bezpośrednio od systemu operacyjnego (GC uzyskuje hurtem, ręczny alokator po mniejszym kawałku), natomiast to co dzieje się później, tj. jak te zaalokowane fragmenty pamięci są przydzielane aplikacji to jest zupełnie inna bajka.
Sprzętowe wsparcie dla segmentacji w żadnym stopniu nie rozwiązuje problemu fragmentacji – eliminuje tylko fragmentację zewnętrzną. Fragmentacja wewnętrzna (w ramach stron pamięci) nadal jest. Do tego dochodzi dużo gorsza lokalność odwołań do pamięci – alokujesz kilka obiektów jeden po drugim i masz bardzo małe szanse, że będą one leżały na tej samej stronie. JVM dokonuje alokacji zawsze z ciągłego obszaru pamięci. Czas odzyskany na alokacjach później jest tracony na przeszukiwaniu sterty, ale znowu to daje się ładnie regulować, no i może być robione równolegle przez osobny rdzeń.
Sumarycznie, jeśli nie stosujesz w C++ specjalizowanych alokatorów, aren i innych fajnych, ale trudnych wynalazków (o czym pisze bies), to ogólna wydajność i pamięciożerność obu strategii jest bardzo zbliżona. Natomiast z GC programuje się dużo wygodniej.
@Królik: A ten .NET/Java to nie używa czasem mechanizmów OS'a na którym działa przy alokacji? Bo ręczna alokacja właśnie na tym polega.
Sprzętowa segmentacja nie eliminuje żadnych problemów per se tylko je właśnie stwarza. To OS może ew. starać się minimalizować to zjawisko i temu służą alokatory płytowe, systemy bliźniaków i temu podobne mechanizmy. Natomiast fragmentację wewnątrz stron na poziomie procesu załatwia za Ciebie albo również bezpośrednio sam system, albo biblioteka C jak to jest np. w Linuksie. Oczywiście pod warunkiem, że alokujesz tyle ile rzeczywiście używasz, bo jak używasz potem tylko części zaalokowanej przestrzeni to już jest Twój problem.
@Królik: A wspomniany przez Ciebie Mark-Sweep niby nie powoduje fragmentacji pamięci? ZTCW nie przesuwa on bloków w pamięci, przez co nie ma mowy o ciągłych obszarach pamięci. Radzę doczytać.
@wojtekm: "A ten .NET/Java to nie używa czasem mechanizmów OS’a na którym działa przy alokacji?"
Używa, ale rzadko i hurtem, jak już wcześniej napisałem. Np. od razu 1024MB. Później w trakcie pracy nie używa, tylko sama wewnętrznie sobie ten obszar dzieli. Jest różnica w zaalokowaniu RAZ, a co chwila w oddawaniu i zaraz zabieraniu pamięci.
Ale i tak nie jest to takim wielkim problemem (w koncu można trzymać pule obiektów) – problemem jest fragmentacja, którą cały czas próbujesz ignorować – wystarczy, że zostanie mi na jednej stronie 1B zaalokowanej pamięci, a cała strona nie zostanie oddana do systemu. Oczywiście skrajny przypadek, bo biblioteka standardowa będzie próbowala na tym obszarze alokować inne małe fragmenty pamięci, ale może już tylko małe, bo większe niż strona nie wejdą. Nie może przesunąć tego bajtu gdzie indziej, na inną stronę gdzie została dziura.
Wszystkie te wynalazki o których piszesz, alokatory płytowe, systemy bliźniaków itp. w ostateczności powodują typowo straty na fragmentację wynoszące ok. 50% zaalokowanej pamięci, choć w pesymistycznym przypadku bywa znacznie gorzej. Do tego jeszcze jest taka zależność, że im lepszy alokator pod względem fragmentacji, tym gorszy pod względem wydajności. I na dodatek problem słabej lokalności odwołań do pamięci nie jest rozwiązany, a to bardzo dużo waży przy obecnych szybkich procesorach i wolnych (względnie) pamięciach.
Firefox 2.x miał z fragmentacją bardzo duże problemy (tam przebicie było rzędu 3x, w nowych wersjach użyli specjalizowanych alokatorów i jest lepiej).
GC poprawia lokalność odwołań do pamięci, oferuje dużo szybszą alokację (różnica wydajności jest taka jak między alloca a malloc), nie marnuje pamięci na dziury nie do wykorzystania, w zamian zabiera nieco pamięci na jeszcze niezwolnione obiekty i potrzebuje nieco czasu na posprzątanie. Co najważniejsze jednak, oba narzuty daje się płynnie kontrolować – z jednej strony możesz uzyskać dużo lepszą wydajność niż w przypadku malloc/free, marnując trochę więcej RAMu, z drugiej możesz skonfigurować to bardzo agresywnie, że strata nigdy nie przekroczy ileśtam % (ale kosztem częstszego odśmiecania).
GC jest techniką lepszą jeśli chodzi o mechanizm OGÓLNEGO przeznaczenia. Natomiast jest gorszy w pewnych specyficznych zastosowaniach (np. kiedy masz do napisania program o prostym schemacie zarządzania pamięcią i samemu chcesz kontrolować wszystko co do bajta).
Prawie dobrze. Błąd który popełniasz to pisanie ,,malloc/free'' w temacie wydajności a myślenie: ,,malloc/free w implementacji z systemu X''. Alokacja za pomocą malloc z tcmalloc jest porównywalnie szybka jak GC — robiliśmy testy na gamedev.pl, pamiętasz?
Sam GC też nie poprawia fragmentacji. To musi być GC kompaktujący.
@mz – potencjalnie możesz przeglądać obiekty poczynając od tych na stercie, ale wymaga to przejrzenia wszystkich obecnych obiektów. Gdyby nie było obiektów wskazujących się wzajemnie, to potencjalnie wystarczyło zliczanie liczności wskazań referencji na obiekt.
Wymusza to strukturę drzewiastą obiektów.
I w zasadzie na tym zakończyłem kilka lat temu implementację mojego naprawdę prostego GC w szablonach C++.
@Królik: Ten argument z problemami z lokalnością to właśnie jest jeden z poważniejszych problemów GC, a nie zwykłej alokacji, bo tu, szczególnie jak masz coraz popularniejsze obecnie NUMA możesz kontrolować wszystko tylko na poziomie OS-a. Za wikipedią (akurat w tych zagadnienaiach dość kompetentną):
http://en.wikipedia.org/wiki/Garbage_collection_%…
"Perhaps the most significant problem is that garbage collectors often exhibit poor locality (interacting badly with cache and virtual memory systems), occupying more address space than the program actually uses at any one time, and touching otherwise idle pages. These may combine in a phenomenon called thrashing, in which a program spends more time copying data between various grades of storage than performing useful work. They may make it impossible for a programmer to reason about the performance effects of design choices, making performance tuning difficult. They can lead garbage-collecting programs to interfere with other programs competing for resources."
Poza tym robisz jeden podstawowy błąd metodologiczny. Otóż w przypadku GC trzymasz tam praktycznie wszystko, łącznie ze zmiennymi lokalnymi dla danego bloku/podprogramu, co musi być potem odśmiecone. W zwykłym systemie, alokujesz pamięć eksplicite gdy świadomie jej potrzebujesz poza obszarem lokalnym, natomiast wszelkie lokalne zmienne lądują na stosie i po pierwsze nie ma tam mowy o _żadnej_ fragmentacji, po drugie jest to znacznie częściej statystycznie wykorzystywany mechanizm, niż ręczna alokacja, a po trzecie i najważniejsze jego zwolnienie nie wiąże się z praktycznie żadnym narzutem wydajnościowym (epilog funkcji).
Oczywiście, że można tak napisać program, żeby sobie w bloku zrobić malloc zmiennej, która poza nim nie jest używana, ale o przypadkach patologicznych tu nie dyskutujemy. Każdy odrobinę rozgarnięty programista wie, że stos to jedyne słuszne miejsce na takie zabawy.
@bies, tak, wiem, że są lepsze alokatory niż domyślny. Problem z syntetycznymi benchmarkami jest jednak taki, że alokowanie i zwalnianie obiektów tej samej wielkości w pętli faworyzuje alokator ręczny – nie ma problemu fragmentacji czy gorszej lokalności odwołań. W takim teście najprawdopodobniej dopiero co zwolniony fragment za chwilę jest zwracany przez malloc() – siedzi sobie grzecznie w cache L1 i wszystko pięknie śmiga. Jednak normalne aplikacje nie alokują w ten sposób.
Napisanie sensownego benchmarku jest bardzo trudne. Niemniej Hans Boehm robił kiedyś naukowy eksperyment na kilku realnych aplikacjach i wychodziło mu, że użycie kompaktującego GC wiele z tych aplikacji realnie przyspieszyło, głównie ze względu na spadek liczby "cache-misses", nawet nie ze względu na szybkość samego kodu alokującego (który jednak jakbyś nie patrzył – jest prostszy i krótszy niż w przypadku nawet tcmalloc).
Jak będę miał chwilę, to odszukam ten papier. Inną ciekawą własnością GC jest, że jak masz b. dużo zbędnej pamięci, to możesz mocno przyspieszyć aplikację przez zwykłą zmianę parametrów, aż do poziomu gdzie alokacja na stercie będzie tańsza niż alokacja na stosie [1] (zmarnujesz 7x tyle pamięci, no ale co z tego – tania jest). Nie zrobisz tego tak prosto przy ręcznym alokatorze.
[1] http://portal.acm.org/citation.cfm?id=31085
@wojtekm: Co do zmiennych lokalnych, to Java robi dokładnie tak samo, a nawet lepiej – więcej zmiennych jest w stanie zaalokować na stosie niż w przypadku C++. Poczytaj o Escape Analysis. Niestety życie nie jest takie piękne i są sytuacje, gdzie musisz zaalokować na stercie – np. w przypadku uniwersalnej klasy String czy inych struktur o dynamicznej wielkości. Typowo zwolnienie takiego obiektu w przypadku generacyjnego GC nie kosztuje nic – w porównaniu z alokacją na stosie, gdzie jednak wskaźnik trzeba przesunąć. Stąd przy odpowiednich parametrach GC może być szybsze niż alokacja na stosie.
BTW: Wikipedia rzeczywiście jest BAARDZO WIARYGODNYM ŹRÓDŁEM, nie ma co!
Wszystkie wymienione problemy odnoszą się do niekompaktujących GC, a więc takich jakie są stosowane czasem w C++, a nie w Javie czy .NET.
@Królik: Co to znaczy więcej zmiennych jest w stanie zaalokować na stosie? Wskaźnik okna stosu jest w stanie dalej przesunąć? Sztuczki ze wskaźnikiami to kwestia optymalizacji kompilatora nie języka.
Co do String-ów, to o ile mnie pamięć nie myli to są to obiekty ze swej natury niemodyfikowalne czyli de facto statyczne , zatem i tu kompilator C/C++ może sobie pozwolić na bezpośrednie podstawienia bez narzutu na stos.
Generlanie z GC, jest tak jak sam już zauważyłeś szybko i fatalnie pamięciowo, albo kompaktująco i bywa problem z wydajnością, a dodatkowo większym "brudzeniem" stron, co jak sam wiesz jest jedną z przyczyn trashingu.
Z mojej strony EOT. Nikt mi nie powie, że implementacja GC na 256kb pamięci ma jakikolwiek sens, a taki dałem przykład na początku i od niego zaczęła się cała dyskusja. Dodam jeszcze, że nie występuje tu problem zarządzania stronami etc. To jest inny świat, inne rozwiązania.
"Co to znaczy więcej zmiennych jest w stanie zaalokować na stosie? Wskaźnik okna stosu jest w stanie dalej przesunąć? Sztuczki ze wskaźnikiami to kwestia optymalizacji kompilatora nie języka."
Może nieprecyzyjnie się wyraziłem. Jest w stanie alokować na stosie to, czego w C++ nie jesteś w stanie na stosie zaalokować, bez znacznej ingerencji w kod i "obsługi specjalnych przypadków".
Przykładowo masz funkcję tworzącą obiekt na stercie:
JakasKlasa* dajMiObiekt() {
// … blabla bla
// return new JakasKlasa(blablabla);
}
I teraz użycie tego w kodzie C++ mogłoby wyglądać tak:
JakasKlasa* mojObiekt = dajMiObiekt();
mojObiekt->zrobCos();
delete mojObiekt;
Myk polega na tym, że analogiczny kod w Javie spowoduje alokację tego obiektu na stosie, a nie na stercie, o ile tylko wywołanie dajMiObiekt zostanie zrobione inline. A że Java potrafi stosować wywołania inline w paru przypadkach, gdzie C++ (nawet z PGO) nie potrafi, to więcej obiektów da się potencjalnie alokować na stosie. Z tego co wiem kompilatory C++ nie potrafią same przekształcać wywołań new() na alokację na stosie, nawet w najprostszym przypadku, jeśli wszystko jest w obrębie jednej funkcji (choć wtedy to akurat programista jest trąba, bo mógł to sam zaalokować po ludzku…).
A, i nie pisz mi, że taki przypadek można ręcznie zoptymalizować w C++ – bo wiem, że można. Ale na tym polega kłamstwo mikrobenchmarków – w praktyce pisze się kod zespołowo, z wielu komponentów, wiele rzeczy robi się do zastosowań ogólnych i wtedy ręczne aplikowanie wielu takich niskopoziomowych optymalizacji w kodzie mija się z celem. Ktoś kto pisze funkcje "dajMiObiekt" może nie mieć zielonego pojęcia o tym, w jakim kontekście ona będzie użyta. Im więcej kompilator potrafi sam zoptymalizować tym lepiej.
"Nikt mi nie powie, że implementacja GC na 256kb pamięci ma jakikolwiek sens"
No patrz, a my głupki kiedyś strzelanki 2D na J2ME na telefony ze 128 kB RAM robiliśmy. I działały płynnie, i lagów na GC nie miały. A implementacje GC w telefonach są dużo gorsze niż to co masz w standardowej pełnej JVM. Ale zgadzam się, że równoczesne uzyskanie dużej oszczędności pamięci i dobrej wydajności jest w przypadku stosowania GC trudniejsze. No cóż, każde rozwiązanie ma swoje mocne i słabe strony.
"Co do String-ów, to o ile mnie pamięć nie myli to są to obiekty ze swej natury niemodyfikowalne czyli de facto statyczne"
W C++ nie są. Ale nie zmienia to faktu, że zarówno w Javie jak i w C++ operacje na Stringach powodują dużo alokacji i dealokacji na stercie i nie bardzo jest jak tego uniknąć.
Odnośnie wydajności GC: zrobiłem mały eksperyment. Mam program, który automatycznie dobiera indeksy w bazie danych za pomocą algorytmu genetycznego. Każda iteracja to kopiowanie jakiegoś osobnika (lista planów zapytań + deskryptory indeksów i tabel) i zastapienie nim jakiegoś innego. Plany zapytań są drzewiaste, mogą mieć różny rozmiar i nie da się ich statycznie zaalokować na stosie. Stąd – cała populacja siedzi sobie na stercie i jest w h*j alokacji. Niektóre osobniki żyją b. długo, niektóre nie przeżywają 5 iteracji.
Odpaliłem ten program na przykładowym zestawie danych, zrobiłem pełne GC, zmierzyłem minimalne zapotrzebowanie na pamięć: 5.8 MB. Pomiary wydajności, z dokładnością do 500 iter / s:
Limit 64MB: 29 000 iteracji / s
Limit 9 MB: 28 500 iteracji / s
Limit 7 MB: 26 000 iteracji / s
Limit 6 MB: 5 000 iteracji / s
Dopiero przy przyciśnięciu go do mniej niż ~20% zmarnowanego RAMu widać wyraźny spadek wydajności spowodowany GC. Przy typowym 50% więcej (alokatory ręczne zwykle tyle naddają na fragmentację), nie ma praktycznie żadnej róznicy.
Oczywiście to jest tylko jeden program, inne mogą zachowywać się inaczej – niemniej pokazuje to, że są takie przypadki, gdzie GC jest b. wydajnym mechanizmem.
Miałem nie odpowiadać, ale zrobię jeszcze wyjątek:
"No patrz, a my głupki kiedyś strzelanki 2D na J2ME na telefony ze 128 kB RAM robiliśmy. I działały płynnie, i lagów na GC nie miały."
I pewnie liczyły na 128-bitowych wektorach w SIMD i były mocno nastawione na szybkość obliczeń i przepustowość… Jak mówię, to nie ta skala, do której próbujesz na siłę dopasować swoje wywody. Tu nie sprawdza się podejście GC tu sprawdza się np. MARS: http://lwn.net/Articles/291803/ Na pozór to zupełnie inne rzeczy, ale gdy programujesz w podejściu "data-driven programming" okazuje się, że mocno ze sobą korespondują i często się wykluczają.
Aha i jeszcze chciałbym wiedzieć skąd bierze Ci się to 50%, jakiś link czy coś, bo szczerze mówiąc z tego co tutaj http://www.citi.umich.edu/techreports/reports/cit… można przeczytać to to o czym piszesz to jakieś Science Fiction.
I jeszcze na koniec, żeby uściślić terminy, którymi się posługujemy:
fragmentacja 50% != zużycie pamięci o 50% większe
Tak było by jedynie w przypadku, gdy wszystie sfragmentowane strony
w rzeczywistości nie przechowywały zaalokowanych zasobów, co z definicji nie może mieć miejsca.
Wystarczy, że wszystkie strony zawierają średnio 1/3 niewykorzystanej pamięci. Przy rozmiarze strony wynoszącym 4kB i małych obiektach jest to bardzo prawdopodobne, szczególnie że obiektów nie można przesuwać pomiędzy stronami. Stąd nie ma znaczenia jak inteligentny alokator zastosujesz, zawsze ten problem będzie, mniejszy bądź większy.
Tu masz linka, że sobie "problemu" nie wymyśliłem: http://blog.pavlov.net/2007/11/10/memory-fragment…
A tu masz linka do artykułu opisującego alokator Hoard:
http://portal.acm.org/citation.cfm?id=356989.3570…
Fragmentacja wewnętrzna waha się od 1,02 do 3,17 x, w zależności od testu. Fajne jest, że średnia alokacja jest dosyć mała (ok. 1,25), ale w pesymistycznym przypadku niestety może być znaczna. Natomiast GC daje przewidywalną ilość utraconej pamięci.
Znam ten blog, zobacz jak sobie z tym problemem radzi np. Windows:
http://blog.pavlov.net/2007/11/11/windows-low-fra…
Tego drugiego linka nie przeczytam bo nie mam płatnej subskrypcji…
Generalnie każde z rozwiązań ma swoje zalety i wady. Nie wątpię, że przy dużej ilości alokacji i dealokacji małych obiektów GC może sprawdzać się lepiej. Pytanie zawsze jest tylko jedno, czy da się takiego przypadku uniknąć i czy trzeba zawsze używać GC. Ja generalnie nie przepadam za GC (niespodzianka
), choć nie uważam go też za zło wcielone pozbawione sensu. Z praktyki wiem, że wszystkie sytuacje z jakimi dotąd się spotkałem, które powodowały w/w zachowanie, wynikały ze złej implementacji a nie z konieczności. Często, jeśli się nie dało szybko tego poprawić wystarczyło wprowadzić coś na kształt cache i we własnym zakresie nim manipulować, w pełni jednak kontrolując użytą pamięć. Wiem że GC dużo rzeczy upraszcza i często się po prostu bardziej opłaca, wówczas nie ma sensu toczyć świętych wojen, nie mniej jednak są dziedziny do których po prostu się nie nadaje.
Na tej konkluzji chciałbym zakończyć. Proste gierki na MIDP niczego w tej materii nie udowadniają, bo są jedynie specyficznym przypadkiem nijak mającym się co całości zagadnienia.
Żeby nie być gołosłownym przytoczę taki przykład: jak myślisz dlaczego IBM mimo iż ma własną implementację Javy dla większości ze swoich platform nie dostarcza specyficznego JVM dla samego Cell-a, mimo iż ten posiada rdzeń PowerPC i wydawało by się, że naturalna wieloplatformowaość tego środowiska powinna pasować jak ulał do heterogenicznej budowy tego procesora?
http://www.ibm.com/developerworks/forums/thread.j…
Pozostawiam to bez odpowiedzi, myślę, że jest zbyteczna.
"Wiem że GC dużo rzeczy upraszcza i często się po prostu bardziej opłaca, wówczas nie ma sensu toczyć świętych wojen, nie mniej jednak są dziedziny do których po prostu się nie nadaje"
Ależ ja nie twierdzę nic innego. Obie techniki mają swoje mocne i słabe strony, i dla obu istnieją sposoby na obejście pewnych problemów. Chodziło mi bardziej o wskazanie, że ręczne zarządzanie pamięcią TEŻ może się wiązać z pewnymi mało oczywistymi problemami i pewnym dodatkowym kosztem.
Natomiast GC daje dodatkowo to, że mocno redukuje koszt wytworzenia oprogramowania i "błędogenność". Trudno to przecenić w dużym projekcie. Dlatego w języku ogólnego przeznaczenia jest jak najbardziej pożądane przynajmniej jako opcja (choć z drugiej strony ciężko zaprojektować język z __opcjonalnym__ GC, tak aby nie pogrzebać połowy możliwych zalet GC). Np. GC w C++ da się? Da się. Ale jest koszmarnie niewydajne.
Chyba nie. Tj. przywiązanie może i przemawia. Ale tak samo przemawia w każdym programiście znającym C++ w miarę dobrze.
Zgadzam się na całej linii: programiści C niech się przesiądą — dobrze im to zrobi. Ale C++owcy nie znajdą dla siebie nic ciekawego.
Jak nie muszę nie używam C++. C, jego prostotę i uniwersalność cenię ponad wszelkie udziwnienia C++, z dwuznaczną i niebezkontekstową składnią na czele oraz programowalnymi template'ami, dzięki którym można napisać poprawny program w C++, którego nigdy nie uda się skompilować…
Tego typu teksty słyszałem przez ostatnie 10 lat często. Zawsze sobie myślę: o, lepiej aby gościu używał Javy/C#/Pythona/Czegokolwiek tylko nie C — będzie mniej wycieków pamięci/przepełnień bufora/segfaultów itp. Możesz oczywiście się nie zgadzać ale programistom C ufam tylko jeśli szczerze tego języka nie znoszą i powtarzają, że używają tylko kiedy muszą.
Bo C nie ma GC? … No tak, bo teraz programista ma nie myslec co pisze, byle pisal szybko i zarabial kase na 'tworzeniu syfu pokroju Facebook' wczytujacego sie szybko ale dzialajacego jak by mu slon na noge nadepnol.
Jestem programista C i nie wyobrazam sobie zostawienia alloc ot tak dla zabawy, co nie mozna powiedziec o programistach Java, bedzie 'new' jest zupelnie olewany, bo trzbea sie spieszyc, biznes nie lubi czekac …
@bies: mam z Twojego postu rozumieć, że używając C++ będę miał mniej problemów z wyciekami pamięci czy segfault-ami? Chyba się przesłyszałem…
Skiter: bo nie ma RAII. GC też może być ale RAII jest sprawniejsze.
WojtekM: oczywiście. Ostatni wyciek miałem chyba ze 3 lata temu kiedy pomyślałem: ,,a napiszę sobie ręcznie new bo trzeba przekazać tablicę znaków do funkcji w C''. Zapomniałem o delete — po prostu. Jak to już znalazłem to sądzisz, że dopisałem delete? Nie, zmieniłem tablicę na vector{char} i zapomniałem o pamięci. Od tego czasu wycieków brak.
Z segfaultami będzie podobnie, bo np. operator [] ma w trybie debug assercję ze sprawdzaniem zakresu. Bo nie przekazuje się: char *buffer, size_t size ale vector{char} &buffer i nie ma mowy aby rozmiar rozjechał się z buforem.
Nie o to chodzi, że w C++ da się pisać jak w C. Da się — ale tego nie nazywam ,,znaniem w miarę dobrze C++''. Chodzi o to, że w C++ da się pisać tak aby proste pomyłki eliminować na etapie kompilacji.
Od kiedy ma asercję?
Od kiedy sobie tam ją dopiszesz? Chodziło mi o operator[] dla własnych klas. Zwykłych tablic nie używam. Zobacz jak to jest zrobione w Boost.Array.
@bies: Podobnie jest w C, kwestia przyjętej metodologii kodowania, nic więcej.
Jak ktoś nie panuje nad kodem to w C++ ma jeszcze więcej szans na wyciek niż w C, ot choćby pierwsza z brzegu niepełna destrukcja obiektów lub ich wielokrotna destrukcja, spowodowana przez domyślny konstruktor kopiujący.
,,Jak ktoś nie panuję nad samochodem to ma więcej szans na wypadek'' — truizm, czyli argument do bani. Przyjmijmy, że jednak znasz język którego używasz.
Metodologia kodowania nie da Ci pól prywatnych w strukturze tak abyś nie mógł manipulować rozmiarem bufora bezpośrednio (typedef struct {char *buffer; size_t size} buffer_t). Nie da Ci automatycznego zamknięcia pliku: {ifstream tmp("/tmp/tempXXX", ios_base::trunc); …} po wyjściu z bloku.
Możesz tylko robić audyt i korzystać z zewnętrznych narzędzi (valgrind, electric fence itp.). Oczywiście korzystanie z zewnętrznych narzędzi jest jak najbardziej ok ale dobrze by było jakby kompilator dokładał coś od siebie. W C nie dokłada (albo dokłada mało).
Jeszcze jedno: błędy nie powstają z niewiedzy. Sądzisz, że te wszystkie wycieki to wynik tego, że programiści nie wiedzieli że trzeba zrobić free(p)? Nie, oni po prostu zapomnieli…
@bies: Piszesz że nie używasz zwykłych tablic tylko Boost.Array, a potem twierdzisz, że sam język jest bezpieczniejszy. Nonens.
To, że składniowo pewne rzeczy możesz rozegrać w C++ w sposób niedostęny w C, nie oznacza, że z definicji w C jest trudniej/gorzej. C++ ma to do siebie, że ułatwiając jedną rzecz utrudnia przy okazji kilka innych, na co przykład dałem wyżej.
Tak jak Ty używasz klas i pól prywatnych, tak ja mogę sobie zdefiniować interfejs funkcji dostępowych i używać go zamiast bezpośredniego manipulowania strukturą. Ty chcesz otwierać pliki tymczasowe per blok programu, ja preferuję ich inicjację podczas startu i zamknięcie przy końcu programu.
Zauważ, że w Twoim podejściu plik się może nie otworzyć i musisz uważać kiedy łapać wyjątki, w moim podejściu nie muszę się tym martwić bo mam całą obsługę w jednym miejscu. I tak można mnożyć przykłady.
To tylko kwestia podejścia. Ty chcesz wyłapywać wszystkie błędy kompilatorem, ja twierdzę, że nie tędy droga. C++ eliminując problemy w jednym miejscu wprowadza nowe klasy problemów w innych miejscach. Już dawno przestałem się łudzić, że jest inaczej, stąd mój szczęśliwy powrót na łono C.
I nawet jeśli _Tobie_ się te wszystkie problemy nie przydarzają to jesteś jedynie wyjątkiem potwierdzającym regułę. W większym zespole i tak Twoje umiejętności zostaną przyćmione przez innych, którym już tak dobrze nie idzie, a kod jak by nie było będzie wspólny, podobnie jak problemy.
I na koniec, żeby już tak na nie teoretyzować, to najlepszym dowodem na to co piszę jest choćby śledzenie rozwoju Qt. Za każdym razem gdy ściągnę jakiś snapshot Qt i QtCreatora i go skompiluję, to mogę być pewien, że nie zdążę dobrze otworzyć projektu jak wyskoczy mi jakiś SEGFAULT. W 90% przypadków się sprawdza. Tyle w temacie.
Żadna kwestia podejścia. Pliki możesz sobie otworzyć na początku. Muteksu już nie. Musisz sekcję krytyczną (możliwie małą) otoczyć acquire()/release(). I zdarza się zapomnieć release(). Dlatego nie ufam programistom C takim jak Ty: nie przyjmujesz do wiadomości, że zdarza się zapomnieć release() (free(), deallocate(), close() itp.).
Qt też nie ufam, z resztą.
Sekcje krytyczne możesz sobie wsadzić w funkcje a te obudować makrem, jak się tak strasznie boisz czegoś zapomnieć. Nawet będzie czytelniej i szybciej, bo wywołanie pojedynczej funkcji z pewnością nie będzie cięższe od wywołania duetu konstruktor/destruktor. Trochę wyobraźni.
Generalnie doszliśmy do momentu w którym po prostu różnimy się światopoglądowo, jak ze słuchawkami…
Jeśli chodzi o C oraz wycieki pamięci i problem fragmentacji sterty to rozwiązaniem w wielu przypadkach może być alokacja pamięci funkcją alloca, nie ma wycieków, nie ma fragmentacji – same zalety
C++ jest bezpieczniejszy od C tak jak Vista z UAC jest bezpieczniejsza od Visty bez UAC. Czyli prościej: daje złudne poczucie bezpieczeństwa.
Pisząc w C sprawdzam kod tysiąc razy, bo wiem, że to tylko przenośny assembler. I wszystko może się w każdej chwili przez najdrobniejszy błąd posypać. Z kolei wielu koderów C++ uważa, że C++ jest na tyle wysokopoziomowy, że ich przed czymkolwiek chroni. Tak, chroni przed prostymi błędami (strzałami w stopę) typu zapomnienie delete – błędami, które znajduje się w chwilę. Przed błędami poważniejszymi nie dość, że nie chroni, to dodatkowo utrudnia ich znalezienie, bo pozwala pisać na tak wysokim poziomie abstrakcji, że wielu rzeczy po prostu nie widać. Zepsuj coś w warstwie niżej (np. konstruktorze kopiującym) i zaraz obrywa ci całą nogę.
Wysoki poziom abstrakcji i słaba ochrona przed błędami (właściwie jej brak) to bardzo niebezpieczna mieszanka.
A, zapomniałem dodać, że oprócz fajnego wzorca RAII chroniącego przed strałem w stopę, C++ w zamian oferuje cały arsenał armat urywających nogę lub coś więcej. Np:
* delete[] zamiast delete
* brak sprawdzenia self-assignment w przeciążonym operatorze =
* template bez specjalizacji dla typów wskaźnikowych (code bloat)
* konstruktory statyczne
* wyjątki w destruktorach
Z całej tej list^W^W^W^W. Aaaa, whatever. Pisz w Javie…
@bies: ja wiem, że Ty jesteś mastah C++ i sobie poradzisz. Ale naukowe eksperymenty w kontrolowanym środowisku wykazały wielokrotnie, że tworzenie softu w językach zarządzanych jest dużo tańsze i mniej błędogenne.
@Królik
Z ciekawości i w celu poszerzenia horyzontów. Podasz jakieś linki odnośnie wyników tych eksperymentów?
Tak. Proszę bardzo, tu jeden na szybko wygrzebany:
http://www.lanl.gov/projects/CartaBlanca/webdocs/…
W każdym razie recenzowane źródło, a nie Wikipedia.
Scala jest naprawdę ciekawą możliwością dzięki połączeniu funkcyjności z obiektowością można stworzyć prawdziwe cuda .
Co do Googla , to zauważcie że ta firma powoli próbuje przejąć cały rynek softu .
Tworzą własny os , stworzyli dodatki które sa stosowane masowo w netbookach , mają mnóstwo aplikacji webowych , mają własny system na komórki a teraz tworzą własny język programowania , zupełnie jakby chcieli stworzyć cała własną platformę jak Ms czy Apple
A niech stworza. Roznica miedzy MS/Apple a Google jest taka, ze Google robi dobry soft.
MS i Apple nie stworzyli chyba żadnego języka programowania? Mylę się?
Jako OS może można byłoby uznać Android, ale jak na razie ma on dość ograniczone zastosowanie (chociaż przyznam – sądzę że w przyszłym roku zadebiutuje on jako system dla desktopów). Dodatki to tylko dodatki, w dodatku nie widzę "masowego" ich stosowania w netbookach. Aplikacje webowe – bez żartów, to ciągle jest śpiewka przyszłości i to pod warunkiem, że nie umrze śmiercią naturalnego braku zainteresowania potencjalnych klientów.
Ale tak, myślę, że czują, że sama wyszukiwarka nie zapewni im odpowiednich dochodów do końca świata i szukają alternatywnych źródeł hajcu. Czy GO to dobra droga? Nie wiem… Jeśli w GO napiszą Androida to może będzie to dobra droga do jeszcze większej dominacji nad światem.
To miało być jako odpowiedź na wpis KRZABRa, nie wiem czemu poszło jako nowy watek…
Języki stworzone przez Microsoft: C#, VB, ASP.NET, M, F#…
Języki stworzone przez Apple: znalazłem tylko język Dylan, ale np. Objective-C jest obecnie rozwijany przez Apple
asp.net nie jest językiem
Jest sposobem programowania…
Podobnie jak najdonioślejszy, Altair Basic!
jeśli "framework" tłumaczyć jako "sposób" to masz rację
W ramach ASP.NET jest zdefiniowany podobny język do JSP – czyli ogólnie coś co łączy HTML + język dodatkowych tagów/komponentów + możliwość osadzania in-line kodu w C#/VB.NET. Taki plik (nieważne czy JSP czy ASP.NET) nie jest ani poprawnym plikiem HTML (choć jako wynik generuje HTML w ramach swojego uruchomienia) ani plikiem w języku programowania Java/C#/VB.NET. Jest więc swoistym językiem programowania – podobnym do PHP na przykład.
Co do F# to skopiowanie Ocamla jest raczej mało twórcze.
Na szczęście w tworzeniu języków, które mają być używane komercyjnie nie koniecznie chodzi o bycie twórczym – twórcze są języki eksperymentalne/badawcze, a później ktoś to adaptuje, wygładza, dokumentuje, zapewnia narzędzie, wsparcie etc.
Z resztą wspomniany Ocaml też nie był aż tak twórczy – bazuje na języku Caml, jest też podobny Standard ML, który bazuje na wielu wersjach i odmianach ML. No a pierwszy ML wzorował składnię na ISWIM i tak dalej… Także nie ma co marudzić
Ciekawą sprawą jest to, że język o takiej nazwie istnieje już od dziesięciu lat. Teraz Google będzie musiało zmienić nazwę swojego języka na coś innego. Jedna z propozycji jest szczególnie warta uwagi
" They should change the name to "god". Why hold back on the level of ambition here."
BTW. Ponieważ ta stronka często szuka tanich sensacji, to proponuję przemianować tytuł niułsa na coś w stylu „Złe Google ukradło nazwę języka od jakiegoś biedaka o którym nikt nie słyszał”
@spy000yps w chwili w której patrze na Twoje komentarze masz 6 plusów za pierwszy komentarz i 6 minusów za drugi. Czyżby te same osoby zgadzały się z pierwszą Twoją wypowiedzią a nie zgadzały z drugą ?
A chrome os to co ?
Również system operacyjny , patrzać się z boku to nie ma innej możliwości aby google nie szykowało się na przejęcie rynku softu w netbookach i desktopach .
Niby te google gadgets , google docs to tylko dodatek jednak sam fakt tworzenia przez google systemu operacyjnego i jezyka programowania o czymś świadczy .
Apple też ma 2 systemy operacyjne i jezyk programowania
ms w sumie też
"“Go” ma być tak szybkie C/C++ "
To ma być tak szybki jak C czy jak C++ ? Bo pomiędzy C a C++ jest duża przepaść wydajnościowa.
Nie przesadzaj, C nie jest aż tak wolne.
Ciekawe czasy, średnio co kwartał słyszy się o The Next BIG Thing w kategorii języki programowania. Buzz, buzz, buzz… a żaden z nich nie ma dobrze zdefiniowanej niszy…
a jednak pythonowi i rubiemu sie udalo
Lepiej niech się D spopularyzuje…
Faktycznie… poczytałem trochę o nim i zapowiada się ciekawie. Niestety na razie jeszcze długa droga przed nim, szczególnie, że nie widzę żadnych bibliotek do tworzenia GUI (na Qt to pewnie nieprędko się doczekamy, ale GTK jest chyba w zasięgu, tylko żeby ktoś się zajął portowaniem). A bez tego to na razie się nadaje do jakiś obliczeń, obróbki danych i ewentualnie na serwery (o ile są już biblioteki do obsługi I/O, IP/TCP, socketów, itp, itd).
Tak się składa, że biblioteki GUI są:
DWT (natywny port z Java SWT):
http://www.dsource.org/projects/dwt
QTD (wrapper na biblioteki QT):
http://www.dsource.org/projects/qtd
GTKD (wrapper na biblioteki GTK)
http://www.dsource.org/projects/gtkd
WXD (wrapper na biblioteki wxWidgets):
http://wxd.sourceforge.net/
+ kilka natywnych, mniej dojrzałych rozwiązań.
Jak dla mnie to takie "nowsze C". Dzieki wsparciu Google ma szanse sie przyjac…
Ale języków naprawdę wysokiego poziomu jak Python, Ruby czy Haskell zastąpić nie ma szans…
Bez urazy ale sądząc po popularności Haskella to Go zastąpi go w jakieś 2 miesiące…
haskella nikt nie uzywa, wiec trudno mowic o jego zastapieniu. haskell, a wlasciwie jego rozwiniecie implementowane przez ghc, jest ulubionym jezykiem entuzjastow programowania funkcyjnego i w tej roli go na pewno go nie "zastapi".
W tym oczywiście nie, chodziło mi o ,,całą'' resztę.
Noż jak można!!! Moim skromnym zdaniem, JS to jeden z najciekawszych języków programowania. To że mało kto tak naprawdę zna ten język to już zupełnie inna historia.
JS jest rzeczywiście potężnym narzędziem, ale mitologizowanie na temat jego tajemniczości jest całkowicie niepotrzebne. Wystarczy groknąć dwie fundamentalne koncepcje: prototypy oraz domknięcia. Dzięki swojej lekkości nadaje się świetnie do zastosowań wbudowanych, a dzięki implementacji dla JVM posiada dostęp do wszystkich bibliotek Javy (to akurat po stronie serwera lub grubego klienta, nie przeglądarki). JS został również wybrany na język skryptowy dla GNOME 3.0.
Qt ma wbudowany JS do skryptów co jest moim zdaniem rewelacyjne. Świetnie się nadaje jako język roszerzeń aplikacji.
Nowsze C z GC już jest – Objective-C
Obj-C to nie C, no chyba że C jest obiektowe, dynamicznie typowane i z refleksją. W sumie mają tyle wspólnego, że kod C można wmieszać w kod Obj-C, co bywa upierdliwe (trzeba obwijać typy C w obiekty Obj-C, np. za pomocą klasy NSValue) i nie wygląda za dobrze (choć spora cześć API Apple jest w C, np. Quartz 2D).
I tak Go i wszystkie inne interpretery i kompilatory są pisane w C.
go nie jest jezykiem interpretowalnym, tylko kompilowalnym do natywnego kodu binarnego (x86, x86_64, lub arm – na platformach obslugujacych pliki typu elf, lub mach-o)
gdybys zajrzal do zrodel sam bys o tym sie przekonal…
btw. kod kompilatora jest na tyle prosty – ze da sie go w 2 wieczory przeczytac/zrozumiec
Nie chodziło mi konkrotnie o Go. Chodziło mi ogólnie o to, że wiekszość kompilatorów i interpreterów dla wymyślanych jezyków pisana jest w C. Ergo C jest jakby matką wszystkich jezyków i najlepiej znać i pisać w C.
Kompilatory zwykle są pisane w języku, który kompilują – jako taki dowód siły i użyteczności języka. MCS jest napisany w C#, FPC w Pascalu.
Co do interpreterów – to tutaj nie ma siły, na końcu musi się pojawić program w kodzie maszynowym. Choć nie przeszkadza to powstawaniu np. PyPy, implementacji Pythona w Pythonie.
A twierdzenie o C jako matce wszystkich języków to jakiś żart co się kupy ni trzyma. Równie dobrze można napisać, że wszystko sprowadza się do kodu maszynowego więc najlepiej znać i pisać w kodzie maszynowym. Język programowania jest narzędziem, i do każdego zadania powinno się dobierać takie narzędzie, które najlepiej pasuje do jego wykonania.
Witek: gcc się właśnie przepisuje z C na C++…
Sunowy javac jest napisany w Javie i dobrze mu z tym
Kompiluje i tak tysiąc razy szybciej niż GCJ napisany w C czy C++ (na jedno wychodzi).
A Sunowa JVM w czym jest napisana?
W C, ale w czym miałoby być, skoro API systemów na których to chodzi jest w C. Jakoś z systemem gadać musi. JVM to jednak trochę inna bajka niż kompilator – robi zdeczko więcej, nie sądzisz?
Jest przecież JNI…
A propos kompilacji, ten benchmark poniżej javac kompiluje 4-krotnie wolniej niż g++.
Racja, bo benchmark jest tak mały, że większość czasu kompilacji to odpalenie JVM zajmuje i interpretacja bytecodu. Żadne HotSpoty i optymalizacje nawet nie zdążą się włączyć, a już jest koniec kompilacji.
Sprawdź na czymś co ma 10 tys. klas.
nie wszystkie. Przykladowo Ada – kiedys byla w napisana w C, aobecnie wymaga sama siebie do kompilacji.
http://golang.org/doc/go_faq.html
Tylko Kenneth Thompson ma brodę więc język raczej nie zdobędzie popularności. http://osnews.pl/tworzysz-nowy-jezyk-zapusc-brode…
Zdobędzie. Przepadłby jakby nie miał brody.
Hihi, język programowania o nazwie Go istnieje już od 10 lat.
http://code.google.com/p/go/issues/detail?id=9
Wpadka.
raczej żenujący jak na język kompilowany do kodu natywnego.
przy takiej wydajności serwery będą ostatnią rzeczą do jakiej ten język będzie się nadawał.
Eee, na serwerach chodzi od diabła i trochę Javy która ma wydajność porównywalną albo niższą. Taniej jest dołożyć kolejnego blade'a do chassis.
Porównywalną lub niższą? Sorry, ale jak platforma, która ma duużo więcej wbudowanych optymalizacji w kompilator, robi PGO, ma dużo lepsze algorytmy GC (z niegeneracyjnym GC mogą się schować), potrafi specjalizować kod na podstawie aktualnego użycia, ma być wolniejsza od czegoś, co ma niby zapewniać ten sam poziom kontroli i jest jeszcze statycznie kompilowane?
Te 30% to chyba zrobili jakiś mikrobenchmark w jednej pętli i rzucili na net, żeby dobra reklama była. Albo porównywali do niezoptymalizowanego kodu C.
Dopóki nie opublikują pełnej metodyki testów, to nie ma co w to wierzyć.
Swoją drogą Java na serwerze ma wydajność bardzo zbliżoną do wydajności najlepszych kompilatorów C, a w paru sytuacjach znacznie lepszą.
Moje serwery twierdzą inaczej.
Wydajność Javy bierze się z GC, który dynamicznie tworzy kod maszynowy, ale sam GC mocno obciąża procesor. Ludzie robiący benchamarki javy robię je dla przykładów, które się nijak mają do programowania w C np. robiąc test metod wirtualnych. Polecam lekturę na blogu jarosława zabiello, była tam całą dyskusja na temat szybkości javy.
JIT?
Obciąża procesor? Niby jak? Gdy skompiluje wszystkie hotspoty, odsuwa się na bok.
@Moro: robiłeś porównanie TEGO samego programu w wersji Javowej i w C, że tak twierdzisz? Ja nie robiłem, ale widziałem porównywalne funkcjonalnością produkty, których wydajność łatwo zmierzyć (bazy danych, serwery www), napisane w Javie i C, i znaczących różnic wydajnościowych w żadną stronę nie było. Np. HSQLDB vs SQLite, H2 vs MySQL, Apache vs Tomcat. Funkcjonalnie bardzo zbliżone, wydajnościowo również.
BTW: napisz mi proszę uniwerslanego quicksorta w C (nie C++), który potrafi sortować za pomocą zewnętrznie dostarczonej relacji porządku, tak aby nie był 10x wolniejszy niż Javowe Collections.sort(). Chłopakom od standardowej biblioteki C jak dotąd się nie udało. Swoją drogą nie widziałem benchmarku, w którym Java oberwałaby tak bardzo, jak C dostaje przy sortowaniu (od C++ i Javy).
A co do blogu Jarosława Zabiello to proszę bardzo – znalazłem tam taki benchmark: http://gist.github.com/87746
Jarkowi Z działa 4x szybciej niż analogiczny kod w C++. Sądząc po długiej dyskusji pod postem (http://blog.zabiello.com/2009/03/28/scala-lang), sprawa nie jest wcale prosta, a automatyczna przewaga wydajnościowa C++ – mocno wątpliwa. W każdym razie twierdzenie, że "programuję w C++ ze względu na wydajność" trzeba umieć bardzo dobrze uzasadnić – inaczej można wypaść tak głupio jak Bolo w tamtej dyskusji. Istnieje cała klasa bardzo silnych optymalizacji, które w C++ nigdy nie będą dostępne, albo będą wymagały bardzo dużego nakładu pracy ze strony programisty. Przypadki, że C/C++ dostaje od Javy będziemy obserwować coraz częściej (kompilator HotSpot jest ciągle rozwijany, kompilatory C++ w zasadzie robią już wszystko co jest teoretycznie możliwe).
A mi działa tak samo (porównywalnie, w przypadku C++ widać nawet która f. wirtualna jest wywoływana — jedna działa odrobinę dłużej). Ale ja użyłem PGO i WHOPR w gcc. Na gcc 4.4.3. 4.5 ma mieć zdecydowanie lepsze PGO. Zatem?
Zatem, jak używasz PGO, to jest tak samo. Tylko nikt prawie PGO (z wyjątkiem może gier) nie używa bo musiałby zamiast po jednej wersji na każdy OS wydawać po tyle wersji ile jest wersji procesora. Czyli bardzo dużo. Większość binarek na Linuksa jest kompilowana albo na 486 albo na 586.
Nie do końca. PGO możesz użyć kompilując na ogólną architekturę (-march=x86_64). Co więcej, możesz z jednego zrzutu danych do PGO budować binarki na różne pomniejsze arch (z x86_64 na amdfam10 np.) – też będzie działać i też dość dobrze.
A co do nieumiejętności użycia kompilatora — zgoda. Ale, jak sam zauważyłeś, nie w przypadku ludzi którym zależy na wydajności.
A większość binarek to raczej jest na i686 i x86_64 — nie przesadzaj…
No dobra, niech Ci będzie. Używam Slacka, tu jest wszystko na 486 i 586. Co do PGO zgoda, niemniej nie widzę, żeby było to masowo stosowane. Po prostu w wielu zastosowaniach nie jest potrzebna kilka % większa wydajność.
Na serwery to tylko erlang
Etam komu są potrzebne takie wynalazki.
Język programowania jest wart tyle ile aplikacje w nim napisane.
I tu na pewno C/C++ jeszcze długo nic nie przebije.
Jeśli chodzi o linuxa to wystarczyło by tylko zadbać o to żeby Qt nie
przeszedł na ciemną stronę mocy i zrobić porządne kompilatory
dla javy czy pythona.
Mi. Długo czekałem na język z przyjazną składnią w którym można by implementować "niskopoziomowe" rzeczy.
Java ma kompilator (javac) i jest on podstawą tej platformy, natomiast jeśli chodzi o Pythona to śmiem stwierdzić, że nie wiesz o czym piszesz.
poczytaj o pypy i mozliwosci skompilowaniu pythona za pomoca pythona do c -> binarki
Cobola też nic nie przebijało przez lata. Fakt, że coś jest popularne, nie oznacza, że jest najlepsze.
COBOL to cały czas jest w kilku miejscach mocno używany. Strach tam zaglądać…
Dlatego nie trzymam pieniędzy w banku (no dobra… nie dlatego… uciekłem z banku na wieść o kryzysie)
Złoto?
@bies: Wiem, mam znajomego, który zawodowo babrze się w Cobolu (coś nawet wspominał, że język nadal rozwija się). Nie zmienia to faktu, że w nowych bankowych projektach rządzi C# i użycie Cobola powoli zaniknie (choć pewnie zajmie to dziesięciolecia).
W sieci istnieje już polskie forum odnośnie języka Go od Google.
Zapraszam na http://golang.org.pl
Na dniach ma powstać wiki i portal
adres wiki: http://golang.org.pl/wiki