🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.c
Article #267894

Re: Ciemna strona C++

#267894
From: Sebastian Kaliszewski
Date: Mon, 24 Dec 2007 13:38
1190 lines
46711 bytes
Sektor van Skijlen wrote:
> Python ma przewagę taką, że posiada odpowiednią *składnię*, a nie że ma jakiś
> "ferstklasowy zbiornik".

Czyli ten zbiornik jest dobrze wpasowany do języka. QED.


>>>>>Ha ha ha. Wielka mi różnica, że tupli nie mogę modyfikować! I to w języku, w
>>>>>którym i tak nawet głupiego consta nie da się zrobić.
>>>
>>>>consta który nie oznacza niezmienności obiektu? ROTFL!
>>>
>>>Niezmienności KTÓREGO obiektu?
> 
>>referowanego.
> 
> 
> No dobrze, więc dlaczego ten const nie oznacza niezmienności referowanego
> obiektu?

Bo nie dotyczy obiektu tylko jednego do niego dojścia. Tuple są immutable, a 
w C++ const z immutable nie ma nic wspólnego. Stąd twoje porównanie jest od 
czapy.


>>>>>>>Tego typu podejście jest pożądane tylko w
>>>>>>>językach, które mają większe rygory bezpieczeństwa, ale one sprawdzają to i
>>>>>>>tak w czasie kompilacji (bo sprawdzanie tego w czasie wykonywania to pic na
>>>>>>>wodę).
>>>>>
>>>>>>Bzdura.
>>>>>
>>>>>Bo nie masz nic więcej do powiedzenia?
>>>
>>>>Bo piszesz tak oczywiste bzdury, że szkoda na to czasu.
>>>
>>>To napisanie słowa "bzdura" jest tym bardziej marnowaniem czasu.
> 
>>Istnienie
> 
> Mów dalej.

Patrz wyżej.


>>>>>>>>>>Tylko czemu interfejs jest tak parszywie niejednolity? begin/end to trochę mało.
>>>>>>>>>
>>>>>>>>>Jak to niejednolity! Jest cholernie jednolity.
>>>>>>>
>>>>>>>>Ależ skąd. Jednolite w miarę są pary vector i deque, map i multimap oraz set 
>>>>>>>>i multiset.
>>>>>>>
>>>>>>>A co jest niejednolitego w vector i list?
>>>>>
>>>>>>Wszystko.
>>>>>
>>>>>"Wszystko" to znaczy "nic" albo "nie wiem".
>>>
>>>>Napisane było poniżej.
>>>
>>>
>>>Napisałeś "wszystko". Jeśli vector i list mają wspólne begin(), end(), size(),
> 
>>O tym napisałem. I na tym się ich "jednolistość" kończy.
> 
> Nie. Napisałeś, że "niejednolite" ma "wszystko". Patrz wyżej.

Sam patrz wyżej. Pisałem wyraźnie o begin/end.


>>>iteratory z dereferencją i inkrementacją wspólne, to znaczy, że jawnie mijasz
>>>się z prawdą. Po co?
> 
>>Trzeba było czytac uważnie.
> 
> Wszystko jest napisane wyżej - a tam napisałeś "wszystko".

Cytat jest pozostawiony...


>>>Powiedz mi najpierw może, dlaczego poniższy program się nie kompiluje:
>>
>>[błedny programik ciach]
> 
> 
>>Bo sort wymaga iteratora o dostępie swobodnym.
> 
> No właśnie. Więc?

Więc taka jest jego specyfikacja w standardzie. Która to specyfikacja jest 
taka sobie.


>>>>A stable sort moża i czasem trzeba użyć i na wektorze.
>>>
>>>Ale co to ma do rzeczy - tłumaczę ci, jak chłop krowie na miedzy: algorytmu
>>>introsort
> 
>>Jakiego q.wa algorytmu introsort? Nie ma w C++ algorytmu intorosort. Jest 
>>sorotowanie w czasie rzędu n*log2(n) na iteratorach o dostępie swobodnym. 
> 
> Zgadza się. A czy lista jest zbiornikiem swobodnego dostępu?

Ale jest drugie sortowanie, które działa na iteratorach sekwencyjnych. To 
jest pomieszanie dwu różnych rzeczy w jednym miejscu. Klasyczny błąd 
projektowy -- "nonseparate concerns".


>>>NIE MOŻNA stosować na zbiorniku, który nie jest zbiornikiem
>>>swobodnego dostępu, bo traci to sens - algorytm ten będzie w tym przypadku
>>>działał wolniej, niż mergesort.
> 
>>>>>a list::sort jest to to samo co
>>>>>std::stable_sort, tylko zaimplementowany w sposób bardziej specjalizowany
>>>>>(stable_sort, tak jak sort, wykonywałby kopie wartości, a list::sort po prostu
>>>>>przestawia węzły na żywca)?
>>>
>>>>Poza tym że wyszedłeś z całkowicie błednych założeń to co z tego?
>>>
>>>A co z tego niby ma być?
> 
>>No właśnie nic.
> 
> Chciałbym, żebyś uzasadnił po prostu, dlaczego uważasz, że std::sort powinien
> mieć wersję pracującą na zbiornikach jednokierunkowych i jak wyobrażasz sobie
> implementację takiego algorytmu.

Nie ma zbiorników jednokierunkowych w C++. Implementację wyobrażam sobie 
przes specjalizację za pomocą traitsów dla iteratorów (tak to powinno być 
zrobione).


>>>>>Lista ma zaimplementowane wewnętrznie te rzeczy, które się tak zaimplementować
>>>>>opłacało ze względu na jej szczególności i specjalizację.
>>>
>>>>To było wyspecjalizowac szablon std::sort dla listy a nie robić niejednolity 
>>>>interfejs.
>>>
>>>Sebek, przestań...
> 
>>Nie zamierzam. Design listy w STL jest cienki.
> 
> Jak twoim zdaniem powinien on wyglądać lepiej?

Wpychanie ni z tego ni zowego sort i splice do listy jest do kitu. Powinna 
być udostępiona metoda iteratora swap -- powodująca zamianę wskazywanych 
elementów. I std::stort czy std::stable_sort ma być specjalizowane iteroatorem.


>>>Obiecaj mi, że następnym razem pomyślisz 7 razy zanim palniesz, ok?
>>>
>>>Co miałby przepraszam robić std::sort dla listy, skoro istnieje jawnie
>>>postawione wymaganie, że std::sort może pracować tylko na zbiorniku swobodnego
>>>dostępu, a std::list takowym nie jest?
> 
>>To niech takiego wymagania nie będzie. Ono jest błędem projektowym. Bo można 
>>mieć łatwo stabilne sortowanie bez mergowania, które jest od merge sorta 
>>wydajniejsze.
> 
> To wciąż można zrobić, jaki problem?

Mixed concrens.
Że standardowy sort nie działa bez randdom access a stable_sort ni z tego ni 
z owego działa.


>>I można mieć sortowanie bez obowiązku zachowania stabilności 
>>dla iteratorów sekwencyjnych. Łączenie dwu ortogonalnych cech jest błedem 
>>projektowym.
> 
> To wszystko również można zrobić!
> 
> Nie ma nigdzie żadnego takiego wymagania, że zbiornik dwukierunkowy musi mieć
> sortowanie stabilne, nie wiem, skąd sobie takie dyrdymały wymyśliłeś.

Nic nie rozumiesz. Po pierwsze nie zbiornik. Wpychanie sortowania do 
zbiornika to jest interface bloat przy równoczesnym sortowaniu po 
interatorach. Sortuje się sekwencje wyznaczane przez iteratory -- i niech 
się tego C++ już trzyma.
Po drugie jedyne dostępne sortowanie dla iteratorów nie-swobodnych to 
sortowanie stabilne.

> Algorytm
> sortowanie szybkiego i niestabilnego można by z powodzeniem dodać do listy.

Nie do żadnej listy. Zlisty w ogóle należy wywalic sortowanie.

> Pytanie tylko: jak to zrobić, zakładając że masz do dyspozycji ciąg elementów,
> po których możesz poruszać się jedynie dwukierunkowo. Słucham.

Po pierwsze to możesz sobie np. zebrać do kupy cały ciąg np 30 iteratorów i 
sortować na tym zebranym fragmencie być może zyskując na wydajności.

Często przyzwoicie zrobione wydajne sortowanie używa wymyślnych metod tylko 
do poziomu fragmentów długosci kilkudziesięciu elementów. Poniżej tego 
opłaca się użyć prymitywnego algorytmu typu insertion-sort.

>>>Rozumiem, gdybyś zaproponował takie rozwiązanie, że istnieje std::stable_sort,
>>>std::quick_sort oraz std::sort, który wybierze, powiedzmy, std::quick_sort dla
>>>zbiornika swobodnego dostępu, a na liście zrobi sort() (i tak się tego nie da
>>>zrobić w obecnych warunkach, ale to jest jeszcze do przedyskutowania).
> 
>>Bez sensu. Zdejmij klapki z krzyżykami z oczu. Ten design jest po prostu 
>>zły. Pomieszano rzeczy ortogonalne takie jak stabilność sortowania i 
>>wymaganie swobodnego dostępu ukrywając wszystko pod nazwą stabilności 
>>sortowania. To jest do dupy.
> 
> Nieprawda. Jeżeli już cokolwiek pomieszano, to pomieszano wymaganie swobodnego
> dostępu z możliwością pracy na części zbiornika.

To jedno drumiemu nie przeszkadza.

> Co masz do zaproponowania przy tak postawionym problemie?

Sensownie zaprojektowany iterator (z metodą swap) problem rozwiązuje.


>>>>>To nie jest kwestia spójności zbiorników.
>>>
>>>>Jest.
>>>
>>>Ale ty wolisz argumenty typu "wszystko chuj".
> 
>>Jak coś jest "chuj" to należy to nazwać po imieni i się nie chrzanić.
> 
> Oraz uzasadnić. Na to czekam już od dłuższego czasu.

Zostało to uzasadnione. Brak separacji problemów, nieortogonalne interfejsy, 
brak użycia możliwości języka przez bibliotekę (która w innych miejsach 
dokładnie tych samych możliwości używa)


>>>>>Lista nie spełnia
>>>>>koncepcji zbiornika swobodnego dostępu, a jedynie zbiornika dwukierunkowego, a
>>>>>koncepcja zbiornika dwukierunkowego nie zawiera operator[] ani metody at().
>>>
>>>>No i co to ma do sort czy splice?
>>>
>>>To, że obie te operacje są specyficzne dla zbiornika std::list?
>>>
>>>BYĆ MOŻE sort nie jest operacją LOGICZNIE specyficzną dla tego zbiornika, lecz
>>>sposób jej implementacji również ma znaczenie dla interfejsu.
> 
>>Właśnie C++ pozwala to zrobić bez plątania w to interfejsu.
> 
> Jak?

Przez specjalizację szablonu.


>>>Do czego chciałbyś zastosować "ogólny sort"? Jesteś w stanie napisać algorytm,
>>>który w środku zawiera sortowanie i pracuje na dowolnym zbiorniku?
> 
>>Nie musze takiego pisać. Wystarczy skorzystać z możliwości specjalizacji 
>>szablonu dla konkretnego typu.
> 
> 
> Załóżmy nawet teoretycznie, że chciałbyś.
> 
> 
>>>list::sort sortuje CAŁY zbiornik i może działać tylko na jednym zbiorniku, bo
>>>przestawia węzły. Ale uwaga: tego algorytmu nie da się wykonać na części
>>>zbiornika.
> 
>>Dałoby się bez problemu, gdyby to było do rzeczy wymyślone.
> 
> No więc właśnie: jak?

iterator z metodą swap().


>>>A wszystkie algorytmy sortujące mają się dać wykonać na części
>>>zbiornika.
> 
> 
>>No i? Nie ma tu żadnego fundamentalnego problemu. Tu jest tylko krzywy 
>>design C++.
> 
> 
> Nawet załóżmy.
> 
> 
>>>Te algorytmy muszą pracować na części zbiornika, bo taka jest gwarancja dla
>>>wszystkich algorytmów (bezsensowna moim zdaniem, ale tak zdecydowano).
>>>
>>>I nie przypadkiem algorytmy sortujące wymagają zbiornika swobodnego dostępu.
>>>
>>>Wynika to stąd, że [ciach]
> 
> 
>>Plączesz się w szczegółach jakiegoś konkretnego algorytmu. Standard 
>>algorytmu nie determinuje
> 
> To nie ma znaczenia.
> 
> 
>>>Żebyś się zesrał, nie jesteś w stanie napisać procedury sortowania ZAKRESU
>>>elementów zbiornika std::list takiego, żeby nie wymagał jednocześnie podania
>>>referencji do samego zbiornika.
> 
> 
>>Nonsens. Wystarczy, żeby zbiornik i jego iterator był odpowiednio 
>>zaprojektowany.
> 
> 
> Zakładając, że istnieje algorytm sortowania, który mógłby pracować na części
> zbiornika dwukierunkowego.

Jego istnienie jest oczywiste.


>>>Co równocześnie oznacza, że nie jesteś w
>>>stanie napisać zewnętrznej funkcji, która przyjmie tylko granice zakresów, i
>>>będzie działała dla listy.
> 
>>Dla takiej jaka jest teraz być może nie. Ale już powiedziłem, ża taka jeka 
>>jest, jest do dupy.
> 
> A jaka nie byłaby do dupy?

Patrz wyżej.


>>>Skoro tak, to nie jesteś w stanie napisać std::sort tak, żeby działało i dla
>>>vectora i dla listy.
> 
>>Jestem.
> 
> No to słucham.

Patrz wyżej.


>>>>>Czy to jest takie trudne do zrozumienia?
>>>
>>>>Widzę, że dla Ciebie tak. Po tych bzdurach co tu powypisywałeś. Pomyli
>>>
>>>Może zacznij pisać w końcu coś do tematu.
> 
>>Ja piszę. Ty błądzisz po jakiś nieistotnych zakamarkach.
> 
> Jedyne co piszesz, to że design STL jest do dupy i że można to lepiej
> wymyślić. Wybacz, na razie nie przekonałeś mnie jeszcze o tym.

Patrz wyżej.


>>>>>O tym, czy taki podział na koncepcje jest słuszny, możemy dopiero porozmawiać,
>>>>>jak będziesz wiedział, jak należy postawić problem.
>>>
>>>>Ja wiem. Ty, jak widzę, wogóle go zgubiłeś.
>>>
>>>Nie widzę, żebyś wiedział - nie napisałeś jeszcze nic poza "bzdura, bzdura,
>>>bzdura".
> 
>>Napisałem jak to powienno być zrobione.
> 
> Napisałeś, że powinno być zrobione - na "jak" na razie czekam.

Patrz wyżej

>>>>>>lista z C++ jest wyjątkowo do dupy. Ponawtykali jakiś rzeczy których nie 
>>>>>>powinno być (sort, merge, itp...)
>>>>>
>>>>>I bardzo słusznie zrobili - na tej samej zasadzie, na jakiej vector posiada
>>>>>metodę reserve(), a list nie.
>>>
>>>>Zrobili do *dupy*. Od tego są specjalzacje szblonów a nie rozpieprzanie 
>>>>interfejsu.
>>>
>>>Specjalizacje szablonów można zastosować pod warunkiem, że jesteś w stanie
>>>ustalić wspólny interfejs, realizowalny dla różnych zbiorników.
> 
>>Wszędzie się daje, tylko w C++ nie...
> 
> W którym przepraszam języku masz możliwość sortowania fragmentu zbiornika o
> dostępie tylko dwukierunkowym?

Nie ma żadnej fundamentalnej różnicy między zbiornikiem a jego fragmentem.


> Z ciekawości, zajrzałem co ma Java. Java posiada algorytm
> java.util.Collections.sort() (w dwóch wersjach, jedna z komparatorem).
> Pierwszym argumentem jest LISTA (nie zakres elementów). W żadnej klasie
> dziedziczącej po *.Collections nie jest ona przesłonięta.
> 
> Co więcej, *.Collections.sort() ma gwarancję, że jest stabilny. Ciekawe,
> dlaczego?

Bo nie dawali wersji niestabilnej?


>>>>>Może twoim zdaniem powinny one mieć wszystkie te same metody, wszystkie te
>>>>>same zależności, wszystkie te same wymagania, a nawet jeszcze niech mają taką
>>>>>samą implementację. Wtedy będą spójne. A nie, cholera, będą miały inne nazwy.
>>>
>>>>Nonsens. Zgubiłeś problem.
>>>>Operacje robiące to samo mają mieć interfejs taki sam. A nie mają.
>>>
>>>Teoretycznie masz rację, tylko pod warunkiem, że jesteś w stanie:
>>>a) zdefiniować wygodny interfejs
>>>b) zrobić implementację do tego interfejsu
>>>
>>>W przypadku std::sort, skoro już o tym mowa, możesz zrobić interfejs, który
>>>wymaga podania, zbiornika, początku i końca, ale nie bęzie on wygodny. Można
>>>zrobić metodę sort dla zbiornika, również z zakresami, ale co wtedy ze
>>>zbiornikami, które nie mają metod, a są sortowalne (np. surowa tablica)?
> 
>>Można też zostawić interfejs taki jaki jest. I dostosować bebechy. To że 
>>sort dla listy będzie tak naprawdę przepinał węzły a nie kopiował elementy 
>>to jest wewnętrzny szczegół implementacji sort wyspecjalizowanego dla listy.
> 
> To w tym celu iterator musiałby mieć referencję do zbiornika.

Nie musiał. swap() dla iteratora wystarczy.

> To nie ma znaczenia, że lista jest zwykle zaimplentowana jako cykliczna, z
> jednym martwym elementem. Iterator tak czy siak nie ma możliwości dowiedzenia
> się, gdzie jest początek i koniec zbiornika.

A po co mu to?

>>>Wspólny i jednolicie opisany interfejs ma sens, jeśli stosujemy go do typów,
>>>które chciałyby mieć ten interfejs jako część swojego generycznego interfejsu.
>>>Jeśli jednak generyczność tego interfejsu nie ma uzasadnienia, to i
>>>ujednolicać go na siłę nie ma po co.
> 
>>Generyczność ma uzasadnienie. Ale została olana.
> 
> Jakie ma uzasadnienie?
> 
> Rozumiem jeszcze, gdyby była wersja generyczna czegoś takiego:
> 
> template <class Container>
> void best_sort( Container& c, typename Container::iterator b,
> 		typename Container::iterator e );
> 
> Natomiast o generycznej z uwagi na omawiane tu warunki wersji algorytmu
> std::sort zapomnij.

Dlaczego mam zapominać o czymś co jest zupełnie oczywiste?


>>>>Dlaczego map::iterator iteruje po parach a vector::iterator nie
>>>
>>>Np. dlatego, że elementami mapy są pary, a elementami wektora nie (chyba że
>>>zrobisz vector<map<A,B>>).
> 
>>To jest błąd w projekcie std::map. Mapa tak jak wektor ma klucze i wartości.
> 
> Od kiedy to wektor ma klucze? Po czym to wnosisz, po tym, że oba zbiorniki
> mają przeciążony operator [] ?

Index jest kluczem.


>>>>-- przecież 
>>>>oba są zbiornikami danych do których można się odwoływac po kluczu -- w 
>>>>przypadku vectora kluczem jest indeks, w mapie obiekt dowolnej 
>>>>porównowywalnego i przypisywalnego typu.
>>>
>>>No tak, oczywiście - popuśćmy wodze fantazji i piszmy bzdury bez
>>>najdrobniejszego przemyślenia.
>>>
>>>Czy zastanowiłeś się odrobinę chociażby nad tym, co praktycznie wałkujemy od
>>>początku tej dyskusji: usunięcie elementu "ze środka" vectora przetasuje owe
>>>klucze dla pewnej liczby elementów, a w mapie nie?
> 
>>vektor spełnia inne niezmiennikni niż mapa. Co nie zmienia częstej 
>>podstawialności jednego za drugie.
> 
> 
> Sebek, skoro już mowa o kompromitacji: czy nie zauważyłeś takiego drobnego
> szczegółu, że skoro mówimy o parach klucz-wartość, to w takim razie usunięcie
> ze zbiornika dowolnego elementu powinno spójność powiązań kluczy z wartościami
> zachować?

Nie musi. To jest właśnie specyfika zbiornika. Inaczej byłaby tylk mapa.


> W przypadku mapy definiując nowe powiązanie, określasz jaki klucz powinien
> mieć przypisany jaką wartość. I to się nie powinno zmienić przy jakiejkolwiek
> operacji na zbiorniku (innej, niż usunięcie powiązania z mapy lub przypisanie
> kluczowi innej wartości).

Tak. A w przypadku vectora już nie.


>>>>Mapa powinna mieć dwa iteratory -- 
>>>>jeden po wartościach
>>>
>>>Po co?
> 
>>Bo tak jest wygodniej i czytelniej? I *spójniej*?
> 
> Ale kto by tego do czego używał?

Prawie nigdy nie zdarzyło msi się, bym potrzebowała na raz klucz i wartość. 
Zwykle potrzebuję same wartości, rzadziej same klucze.


>>>>i *inny* po kluczach (tylko stały).
>>>
>>>Przecież wystarczy w zupełności, że i->first jest stałe, a i->second
>>>modyfikowalne.
> 
>>Ale i->first nie jest stałe :) BANG!
> 
> Od kiedy?
> 
> /usr/include/c++/4.1.1/bits/stl_map.h:
> ...
>  class map
>     {
>     public:
>       typedef _Key                                          key_type;
>       typedef _Tp                                           mapped_type;
>       typedef std::pair<const _Key, _Tp>                    value_type;
>       typedef _Compare                                      key_compare;
>       typedef _Alloc                                        allocator_type;

Szczegół jednej implementacji.


>>>>Zbiór zaś powinien 
>>>>mieć tylko stały iterator -- po kluczach. Nie stały interator w zbiorze to 
>>>>jest w ogóle kompletna porażka.
>>>
>>>To chyba jest jakiś błąd specyfikacji - w gcc na przykład masz tak:
>>>
>>>      typedef typename _Rep_type::const_iterator iterator;
>>>      typedef typename _Rep_type::const_iterator const_iterator;
> 
>>Szczegół implementacyjny. Szkoda że nieprawdziwy już dla mapy.
> 
> No bo iteratora nie można uczynić stałym, jeśli ma wskazywać na modyfikowalny
> obiekt. Jakie to ma zresztą znaczenie?

Takie że się kupy nie trzyma.


>>>Więc ja tu nie widzę problemu: on ma i tak zawsze stały iterator. Różnica jest
>>>tylko taka, że POSIADA typ iterator. I bardzo dobrze, że posiada, bo niektóre
>>>algorytmy się do takiego typu próbują odwoływać.
>>>
>>>Jest zatem typ iterator, ale operator* użyty na nim zwróci ci stałą
>>>referencję. Czyli jest ok.
> 
>>Czyli jest dziwnie. Były zresztą na ten temat flejmy na c.s.c++
> 
> To nie czytałem.
> 
> 
>>>>>A tu się zgadza - już nawet Seweryn podał implementację, chociaż mam poważne
>>>>>wątpliwości, czy rzeczywiście jest sensowna.
>>>>>
>>>>>Tylko że akurat to jest dla mnie głupie. Nie po to pytam, żeby tylko zadać tak
>>>>>sobie pytanie, tylko dlatego, że chciałbym następnie wykonać na znalezionych
>>>>>danych jakąś operację - i to dla mnie robi equal_range.
>>>
>>>>Nie zawsze chcesz od razu robić jakąś operację. Całkiem często robi się np. 
>>>>walidację danych, itp.
>>>
>>>To wtedy używasz binary_search.
> 
>>ROTFL!!!
> 
>>binary_search na mapie!
> 
> A co, bo nie rozumiem.

Przeczytaj sobie jakich iteratorów wymaga binary_search...


>>>>>>>>>>>Poza tym nie wiem, dlaczego właściwie uważasz, że vector jest bardziej
>>>>>>>>>>>uniwersalny, niż list.  To prawda, że vector nadaje się do tzw. "większości
>>>>>>>>>>>zastosowań", ale ma jedną bardzo paskudną wadę: unieważnienie iteratorów
>>>>>>>>>>>następuje tam po każdej modyfikacji liczebności zbiornika.
>>>>>>>>>
>>>>>>>>>>Po każdej po której zmienia się capacity. capacity zaś zmienia się tylko 
>>>>>>>>>>czasami.
>>>>>>>>>
>>>>>>>>>Weź ty się z łaski swojej nie ośmieszaj, dobrze?
>>>>>>>
>>>>>>>>sam się ośmieszasz. Te gwarancje są po to, by można było określone 
>>>>>>>>konstrukcje wykonać.
>>>>>>>
>>>>>>>Konkretnie które gwarancje?
>>>>>
>>>>>>Ważności iteratorów po określonych operacjach.
>>>>>
>>>>>Ty cały czas nie rozumiesz.
>>>>>
>>>>>Ile znasz algorytmów, w których ze zbiornika swobodnego dostępu usuwa się
>>>>>elementy od końca? Ja znam tylko jeden przypadek - tylko wtedy, gdy ten
>>>>>zbiornik jest stosem.
>>>
>>>>To cienki jesteś :-P. Od końca to nie znaczy kolejne od końca. Po prostu 
>>>>jadąc od końca.
>>>
>>>Lol, czemu ty się aż tak kompromitujesz.
> 
>>Ja? skąd! Ty za to na całej linii :)
> 
>>>Czy fakt, że usuwasz elementy od końca, czy od początku zmienia ci w efekcie
>>>końcowym cokolwiek nt. unieważniania iteratorów?
> 
>>Sektor ty jesteś expertem od C++??!?
> 
>>Weź że q.wa zajrzeyj w końcu do standardu tego twojego ukachanego, 
>>popier.lonego języka!
> 
> Owszem, jestem.

Zaczynam mieć wątpliwości.

> 
> O co chciałeś w tej wypowiedzi powyżej zapytać?

To popatrz do tego standardu i przeczytaj sobie co i kiedy unieważania 
iteratory i który iterarory.


>>>>Poza tym jak masz ze zbiornika 30 elementowego usunąć 
>>>>elementy 5, 13, 17 i 28 to jadąc od końca możesz to zrobić.
>>>
>>>To TYLKO jadąc od końca możesz to zrobić. Bo w przeciwnym razie, po usunięciu
>>>elementu #5, element 13 nagle stanie się 12 i podobnie reszta.
>>>
>>>Bardzo fajnie, że znasz algorytm selektywnego usuwania elementów z wektora,
>>>ale wybacz, to nie ma nic zupełnie do tematu, który wałkujemy.
> 
>>Ma. Tematu nie udało ci się uściślić przez 5 postów...
> 
> Nie ma. I przestań z łaski swojej stosować wciąż taktykę "jesteś za głupi,
> żeby zrozumieć, jaki ja jestem mądry".

Sektor, ty widzisz swoje końcowe rozwiązanie i przez jego pryzmat patrzysz 
na całość. Ale ani nie ma pernowści że ono jest optymalne ani też nikt poza 
tobą nie zna całości.


> Przypomnę ci - skoro zapomniałeś najwyraźniej - że chodzi nam cały czas o
> zbiornik, w którym usuwanie elementów pozwala na zachowanie ważności
> iteratorów do pozostałych elementów, żeby można było je szybko usuwać.

Patrzysz przez pryzmat swojego rozwiązania. Mówisz o konkternej drodze do 
celu, a interesuje nas tylko cel fo którego drobi mogą być różne.

> Na razie bez większych sukcesów usiłujesz udowodnić, że nadaje się do tego
> wektor.

Ponieważ nadal nie podałeś wystarczająco kompletnych uwarunkowań to wektor 
mioże się nadawać a może nie.
Pamiętaj -- nikt poza tobą nie ma przed oczami twojego rozwiązania.

>>>>I co ważne 
>>>>zapewne okaże się, że tak jest lepiej niż użyć map (bo samo dodanie elementu 
>>>>do map jest o 2 rzędy wolniejsze niż dodanie do vector).
>>>
>>>Zgadza się bezsprzecznie.
>>>
>>>Tyle że dodanie tego elementu na końcu wektora unieważnia ci od razu wszystkie
>>>iteratory (co prawda, nie unieważnia ci indeksów, ale to niewiele zmienia, bo
>>>unieważnia je przy usuwaniu). No chyba że na poważnie myślisz o tym, żeby
>>>sprawdzać ilość zarezerwowanego miejsca przed każdym dodaniem elementu - na
>>>upartego, owszem, masz gwarancję, że iteratory nie będą unieważnione, jeśli
>>>dodanie elementu przydzieli miejsce z zapasu.
>>>
>>>Natomiast dodanie tego elementu do listy jest nieco wolniejsze od wektora (ale
>>>bardzo nieznacznie - nie aż tyle, co w przypadku std::map),
> 
>>Bardzo znacznie. Zwykle też o 1-2 rzędy wielkości :) To jest lepiej niż o 
>>2-3 rzędy wielkości dla mapy, ale też słabo.
> 
> Nie sądzę, żeby można było dywagować nt. różnic złożoności algorytmów w
> przypadku, gdy w grę wchodzi alokacja pamięci.

Owszem wchodzi. W przypadku listy za każdym dodaniem elementu, w przypadku 
vectora tylko czasem (tak żeby amortyzowało się na coraz więcej dodań).


>>>>Nigdzie ci nie kazałem usuwać wszyskich elementów ze zbiornika. Mogłeś mieć 
>>>>np. listę elementów do usunięcia i chcieć usunąć tylko te.
>>>
>>>Ok - załóży nawet, że spróbuję nieco potraktować poważnie to, co piszesz.
>>>
>>>Załóżmy. Mamy wektor z elementami opisującymi połączenia.
>>>
>>>Mamy cykliczne sprawdzanie połączeń. W jednym cyklu okazało się, że odpadły
>>>trzy połączenia z 10: połączenia o numerach 2, 4 i 9.
>>>
>>>Każdy z obiektów połączenia trzymał swój indeks zapisany w polu. W związku z
>>>tym, wiemy że należy wywalić ze zbioru połączeń połączenia o indeksach 2, 4 i
>>>9. Możemy sobie nawet zrobić tymczasowo vector<int>, który będzie je
>>>przechowywał.
>>>
>>>No więc wykonujemy naszą operację. Sortujemy nasz wektor z identyfikatorami
>>>połączeń (indeksami do wektora z połączeniami) malejąco, a następnie po kolei
>>>usuwamy nasze połączenia.
>>>
>>>Usuwamy najpierw #9. Jest to ostatni element, więc nikt na tym nie ucierpi.
>>>
>>>Usuwamy następnie #4 i #2.
>>>
>>>W tym momencie okazuje się, że musimy przenumerować wszystkie obiekty od #2
>>>(ostatniego elementu z listy indeksów po posortowaniu) do końca zbiornika, bo
>>>element #3 stał się teraz #2, #5 - #3, #6 - #4 i tak dalej.
>>>
>>>Nie jest to trudna operacja, ale wystarczy fakt, że w ogóle trzeba ją wykonać,
>>>i że ma ona liniową złożoność.
>>>
>>>Uważasz, że to efektywny sposób gospodarowania zasobami?
> 
>>Może się okazać, że tak :)
> 
> Może jest szerokie i głembokie.

Być może.

>>Brak odwołań do stery może przynieść zysk o 1-2 
>>rzędy wielkości. I wtedy cudowanie może się opłacić.
> 
> Niestety nie w moim przypadku. Rozumiem, że dla powyższego rozwiązania można
> by znaleźć określoną niszę, ale pomińmy na razie nisze.
> 
> Skoro już wspomniałem, że lista przechowuje obiekty z informacją o
> utrzymywanych połączeniach TCP, jakie widzisz tu przeciwwskazania dla
> std::list, zakładając że tworzenie nowego elementu następuje w momencie
> wyjścia z accept()?
> 
> Bo ja przeciwwskazań dla wektora i mapy co nieco widzę.
> 
> 
>>>>>>>A ty mi tu proponujesz jakieś śmieszne
>>>>>>>usuwanie od końca?
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>>Tyle że jest to mało wydajne i nie ma nic wspólnego z szybkim usuwaniem.
>>>>>>>
>>>>>>>To nie ma nic wspólnego z jakimkolwiek usuwaniem, ani z jakąkolwiek mającą
>>>>>>>sens operacją, jeśli rozpatrujemy przestrzeń rozwiązań przemysłowych, a nie
>>>>>>>akademickich rozważań.
>>>>>
>>>>>>W "przestrzeni rozwiązań przemysłowych" dla dużej liczby małych struktur to 
>>>>>>sie może opłacać (struktury po kilkadziesiąt pozycji których jest wiele -- 
>>>>>>pomagamy cache locality).
>>>>>
>>>>>Tak, ale nie stosowane w taki sposób. Jeśli już, to można kombinować z
>>>>>std::deque, albo czymś podobnym (w sensie, lepiej kontrolowanym).
>>>
>>>>std::vector jest zupełnie dobrze kontrolowany i przy większej liczbie 
>>>>operacji zachowuje ważność iteratorów.
>>>
>>>Czy jesteś w stanie podać mi przynajmniej JEDNĄ taką operację, która
>>>modyfikuje wektor, nie unieważnia iteratorów, i która w tym celu nie wymaga
>>>żadnych dodatkowych wstępnych założeń poza poprawnością danych wejściowych?
> 
>>A co to ma do rzeczy? Zobacz kiedy nie zachowuje iteratorów deque i porównaj 
>>sobie co jest "bardzuiej kontrolowane".
> 
> Bardzo ładnie wykręcasz się od odpowiedzi - oczywiście, deque nie ma nawet
> takich gwarancji, jak wektor, ale jakie to ma dla mnie znaczenie, skoro nawet
> gwarancje, jakie daje wektor, dla powyższych wymagań można o kant dupy rozbić?
> 
> 
>>>>>Jeśli każdy istniejący obiekt siedzi w liście, to każdy ma zapisany swój
>>>>>iterator. W efekcie jestem w stanie każdy z nich usuwać z listy w czasie
>>>>>stałym.
>>>
>>>>A skąd mam wiedzieć, że te obiekty są jeszcze trzymane przez co innego 
>>>>(czyli jest do nich innny dostęp niż z kontenera je przechowującego)
>>>
>>>Nie ma do nich dostępu znikąd innąd, niż z kontenera je przechowującego. Skąd
>>>ci to w ogóle przyszło do głowy?
> 
>>To po cholere ci trzymanie indeksów czy iteratorów w samych elementach? 
> 
> Z bardzo prostej przyczyny. Bo jest to jedyna możliwość zidentyfikowania tego
> elementu w zbiorniku.

1. Nie wierzę, że jedyna.
2. Masz zakręconą strukturę własności: zbiornik ma elementy które z kolei 
mają zbiornik i się same z niego usuwają. Jesteś pewien, że tak było 
najprościej? (byc może faktycznie tak było najprościej, ale musisz mnie 
przekonać).

> Dotarło?

Na razię widzę, że jesteś mocno przywiązany do swojego rozwiązania.


>>Sektor -- albo projekt jest bezsensownie skomplikowany (a więc do kitu) albo 
>>właśnie oszukujesz.
> 
> No dobrze, powyższe wyjaśnienie powinno cię naprowadzić.
> 
>>Jak kontener (lista czy vector) jest jedynym dojściem do przechowywanych 
>>obiektów to iterator bądź indeks masz dany przez sam fakt sięgnięcia do tego 
>>obiektu.
> 
> Zakładając oczywiście, że mówimy o zbiorniku intruzyjnym. 

Ależ skąd. W chwili gdy odowłujesz się do a[x] musisz znać x. Ty jak 
rozumiem tracisz tę informację po to, by ją ponownie odgrzebywać poziom 
niżej. Tak?

> Zbiornik std::list
> niestety takowym nie jest, std::vector również. No, na upartego można przyjąć,
> że jest tak w przypadku surowej tablicy, ale z niej usuwać elementów się nie
> da.

Nie ma znaczenia.


>>>>>Jeśli nie przedstawiłem żadnych szczególnych warunków, przy których
>>>>>można poszukać odrębnego lub prostszego rozwiązania, to znaczy, że takowych
>>>>>nie ma.
>>>
>>>>Nie przedstawiłeś warunków wystarczających.
>>>
>>>
>>>Dobrze - skoro chcesz już uprawiać taką zabawę intelektualną, to proszę
>>>bardzo: napisz mi tutaj dokładnie, jakie przedstawiłem warunki, gdzie te
>>>warunki są niedokładne lub co jest nie sprecyzowane.
> 
>>Patrz wyżej :)
> 
> Nie widzę.
> 
> Proszę o drobne podsumowanie wątpliwości, bo na razie to mówisz, że "a, te
> warunki są w ogóle niespójne".

Nie wiadomo co trzyma te twoje obiekty poza zbiornikiem (a jakiś inny 
kontakt ze światem zdaje się mają). Nie wiadomo czy usuwasz po jednym czy 
grupowo (jak się trochę zbierze). Kto inicujeje akcje prowadzącą do 
usunięcia. I peweni jeszcze torchę...


>>>>>>>Nadal czekam na propozycję rozwiązania tego w tym wszystkowyrażalnym Pythonie.
>>>>>
>>>>>>To już powiedziałem -- słownik
>>>>>
>>>>>Jest to - jak powiedziałem - rozwiązanie spełniające, owszem, wymagania (i -
>>>>>co ciekawsze - w językach skryptowych wszyscy je stosują), niestety słabe w
>>>>>stosunku do std::list z uwagi na:
>>>>>- konieczność generowania kluczy (wartości iteratorów std::list są same z
>>>>>  siebie unikalne na całą aplikację)
>>>
>>>>hash(object) działa całkiem dobrze.
>>>
>>>hash(object) tworzy unikalny klucz do obiektu? Od kiedy?
> 
>>Od zawsze? Dopóki nie zrobisz własnej implementacji którw to psuje.
> 
> 
> A, ten hash.
> 
> No dobrze. Powiedzmy, że ten problem odpada, ale i ma on niewielkie znaczenie.
> Gorzej z tym drugim.

Drugi miał być logarytmiczny, a nie jest.


>>>>>- logarytmiczny czas znajdowania węzła w zbiorniku (przy stałym czasie w
>>>>>  przypadku std::list)
>>>
>>>>Ależ ten czas nie jest logarytmiczny -- jest stały (zamortyzowany) :)
>>>
>>>Amortyzacja polega na tym, że tylko jedna na kilka operacji ma złożoność
>>>gorszą niż stałą. Tymczasem czas wyszukiwania elementu po danym kluczu będzie
>>>miał określoną złożoność forever, za każdym razem, gdy jest wyszukiwany.
> 
>>Amortyzujesz po wyszukiwaniach wielu obiektów a nie wielokrotnym 
>>wyszukiwaniu tego samego (bo to ma nikły sens).
> 
> 
> No dobrze, nawet zakładając zamortyzowany stały, jego amortyzacja nie jest tym
> samym, co amortyzacja w przypadku dodawania elementów do wektora (bo nie
> możesz jej przewidywać, ani jej kontrolować). Wciąż jest to złożoność gorsza,
> niż stała.

Nieznacznie. Będę się martwił jak to będzie przeszkadzać. Nie będę się 
martwił na zapas.

>>>I pod warunkiem, że hash ci dobrze wyhaszuje obiekt, bo równie dobrze może ci
>>>zrobić "rzadkie drabinki" i cała "amortyzacja" weźmie w łeb.
>>>
>>>No więc dobrze, załóżmy nawet teoretycznie, że jesteś w stanie uzyskać lepszy
>>>czas, niż logarytmiczny (kosztem większego zużycia pamięci swoją drogą) - ale
>>>stuprocentowo stałego czasu (co gwarantuje ci std::list) nie uzyskasz i tak.
> 
>>Jeśli jest good eqough to się nie będę przejmował. Jeśli nie to się będę 
>>wtedy martwił. Zacznę od odpalenia psyco.
> 
> Powodzenia.

Mi działa. Przyspiesza czasem i kilkadziesiąt razy.


>>>>Btw w Pythonie każdy obiekt domyślnie 
>>>>może być kluczem -- trzeba by mu tego jawnie zabronić.
>>>
>>>No, możliwe - ale co to ma do tematu? 
> 
>>To, że nie potrzebujesz mapy tylko set.
> 
> No dobrze, niech będzie set. Co to zmienia?
> 
>>>BTW ciekaw jestem jak w takim razie te
>>>obiekty mają zdefiniowane porządkowanie.
> 
>>Porządkowanie nie jest potrzebne. Potrzebny jest dobry hash.
> 
> I trochę pamięci.

To jest potrzebne tak czy siak. I tak jest lepiej niż parę innych rozwiązań.


>>>>>>>>Nie robię. Bezpieczna implementacja Pascala jest możliwa i jest naturalna. W 
>>>>>>>>odróżnieniu od bezpiecznej implementacji C czy C++.
>>>>>>>
>>>>>>>Jasne - po pozbawieniu Pascala np. wskaźników.
>>>>>
>>>>>>Akurat wskaźniki nie przeszkadzają w bezpiecznej implementacji jeśli nie 
>>>>>>masz na nich arytmetyki (a oryginalny Pascal AFAIR nie miał).
>>>>>
>>>>>Czyżby? I masz udokumentowaną obsługę sytuacji wyjątkowej w przypadku
>>>>>zerowego lub wiszącego wskaźnika?
>>>
>>>>Mogę bez problemu mieć taką implementację. Bezpieczna implementacja C (oraz 
>>>>C++) jest praktycznie niemożliwa.
>>>
>>>Z czego to wynika?
> 
>>Z pomieszania tablic i wskaźników. Z wpuszczenia niekontrolowanych typów 
>>gdzie można biegac po ich reprezentacji, itd...
> 
> Można zrobić "not implemented" :)

To już nie będzie C ani C++...


>>>>>>>>>>Co do przykładu -- na sieci pełno.
>>>>>>>>>
>>>>>>>>>To znajdź i wklej - dopóki tego nie zrobisz, dla mnie bredzisz od rzeczy.
>>>>>>>
>>>>>>>>Nie jestem proxy do google. Oczywistości szukaj sobie sam.
>>>>>>>
>>>>>>>Twoje oczywistości to dla mnie brednie - i obaj wiemy, że tylko ja mam z tego
>>>>>>>ubaw.
>>>>>
>>>>>>Ja tam mam niezły. Zwłaszcza gdy wymyślasz bzdury -- zrób sobie google 
>>>>>>python container i nie ośmieszaj się.
>>>>>
>>>>>Zrobiłem. Tylko jestem za leniwy, żeby ci wkleić te pierwsze 10 linków i
>>>>>udowodnić, że nic nie ma na temat wspomnianego zbiornika.
>>>
>>>
>>>>Zrobiłeś? ROTFL! A 2, 5 i 6 link sprawdziłeś?
>>>
>>>
>>>We wszystkich sprawach, w których uważasz, że masz rację, i chcesz to
>>>udowodnić, potrafisz rzucić odpowiednim linkiem.
>>>
>>>W tej jednej tego nie robisz. Taktyka "jesteś za głupi, żeby zrozumieć, jaki
>>>jestem mądry" to naprawdę tani blef.
> 
>>Podałem ci numery linków na stornie którą jakoby sprawdziłeś.
> 
> Wybacz, nie wierzę. Google potrafi nawet za dwoma sąsiadującymi wywołaniami
> wyszukiwania zwrócić zupełnie inny zestaw linków.
> 
> Proszę o link - wklejenie linka nie jest trudne, natomiast uparte jego
> niewklejanie oznacza niewiedzę.

http://docs.python.org/ref/sequence-types.html
http://www.eso.org/~almamgr/AlmaAcs/OnlineDocs/ACS_docs/py/Acspy.Container.html


>>>>>Aha, o tym, że niektórym zdarzało się nazywać słownik również tablicą
>>>>>dynamiczną, również nie słyszałeś?
>>>
>>>>Zapewne stosowali się do przyjętej terminologii jak autorzy STL (czyli marnie).
>>>
>>>Niewykluczone - to niewiele zmienia. A już na pewno nie zmienia niczego w
>>>kwestii tego, czy istnieje coś takiego jak "ustalione konwencje nazewnictwa".
> 
>>Tak, istnienia takich konwencji "nowatorskie" podejście autorów STL nie zmienia.
> 
> Nie jest wcale takie nowatorskie, jak ci się wydaje.

Zdążyli już zmulić całką dużą grupę ludzi...


>>>>>>>>Dałoby się, gdyby całość zaprojektowano a nie zrodzono z chaosu. Jak są 
>>>>>>>>idiotyzmy w stylu vector<bool> to być może nie bardzo da się inaczej, by to 
>>>>>>>>jeszcze było używalne jakkolwiek.
>>>>>>>
>>>>>>>A co złego jest w vector<bool>?
>>>>>
>>>>>>To, że nie jest kontenerem booli tylko pewnego śmiesznego typu 
>>>>>>vector<bool>::reference?
>>>>>
>>>>>I co w tym złego?
>>>
>>>>Że to nie jest referencja.
>>>
>>>W jakim sensie nie jest to referencja?
> 
>>WE najbardziej podstawowm. To nie jest bool&
> 
> A po co musi być to bool& ? Referencją nie jest się poprzez posiadanie & w
> nazwie, tylko poprzez spełnienie odpowiedniej koncepcji. Przynajmniej w
> przypadku generycznego programowania.

W przypadku C++ i referencji to nie bardzo -- o ile wskaźniki emulować da 
się, to referencji nie.

>>>Natomiast uważam, że można by to weryfikować skrośnie i nawet ewentualnie
>>>umożliwiać uzyskiwanie listy propagowanych wyjątków dla każdej poszczególnej
>>>funkcji.
> 
>>Tylko pod warunkiem pełnej dostępności źródeł lub wyjścia poza głupi linker 
>>C. Oba są praktycznie niemożliwe.
> 
> 
> Lub poprzez możliwość umieszczania tej informacji w plikach pośrednich i
> wynikowych.

Czyli wyjściem poza głupi linker C.


>>>>>Anyway, nie wiem, czy nie wystarczyłoby coś w rodzaju platformy w podobnym
>>>>>stylu, co robi C#. W sensie, że niby masz ograniczenia platformy, ale i tak
>>>>>program wykonuje się na platformie natywnej.
>>>
>>>>???
>>>>Program C# jest kompilowany do CIL i wykonuje się na VM z .Net.
>>>
>>>Nie ma czegoś takiego, jak VM z .NET, jeśli mówimy o powszechnym rozumieniu,
>>>czym jest maszyna wirtualna.
> 
>>No właśnie w powszechnym rozumieniu to to jest VM. VM nie oznacza interpretera.
> 
> 
> VM oznacza oddzielne środowisko wykonawcze, obojętnie jak zrealizowane.
> 
> Program w CIL-u nie jest wykonywany w oddzielnym środowisku wykonawczym,
> przynajmniej tak to jest w powszechnym rozumieniu.

Jak nie jak tak? Masz runtime .net który jest właśnie tym oddzielnym 
środowiskiem wykonawczym.


>>>>Ta VM jest 
>>>>realizowana całkiem wydajnie jako JIT ale wirtualizacja cały czas jest.
>>>
>>>
>>>Wirtualizacja jest czysto teoretyczna - kod w CIL-u, który dochodzi już do
>>>etapu wykonywania, jest kodem wyłącznie natywnym. Goście od .NET jasno piszą,
>>>że język CIL nigdy nie był pisany z uwzględnieniem możliwości implementacji
>>>jako VM. Od zawsze miał być tylko i wyłącznie kompilowany JIT-owo.
> 
> 
>>To jest głeboko zaszyty szczegół implementacyjny. Współczesne JVMy też są 
>>JITami -- ale to w najmniejszym stopniu nie zmienia faktu że są VMami.
> 
> 
> Tak, ale pomijasz dość istotny szczegół: w C# możesz pisać kod sprawdzany i
> niesprawdzany, możesz używać wskaźników i możesz przypinać obiekty w miejscu,
> w którym siedzą w pamięci, żeby ich odśmiecacz nie przesunął.

Ale to jest nadal część środowiska wykonawczego.

> Jeśli mamy program napisany z użyciem takiego ficzera, to znaczy że nam się
> ta część wymyka spod kontroli VM. Efektywnie, program NIE JEST wykonywany
> przez żadną VM, bo nie jest to już hermetycznie zamknięte środowisko
> wykonawcze.

To że coś nie jest odśmiecane nie oznacza że nagle wyszło poza VM. Znaczy 
tylko tyle, że nie jest odśmiecane (a więc np. nie jest relokowane za plecami).


> Jest to - znów - wyłącznie kwestia tego, że istnieje bramka między maszyną
> wirtualną, a platformą natywną.
> 
> Nadal nie jesteś w stanie napisać w Javie kodu natywnego.

W C# tak samo...


>>>>Na wielu OS możesz mieć te same adresy logiczne po obu stornach -- wtedy 
>>>>całkiem normalnie to się robi.
>>>
>>>Jeśli już stwierdzasz, że "na wielu OS", to znaczy że nie jest to rozwiązanie
>>>przenośne.
> 
>>Działą na każdym nowoczesnym Posixie, nawet na archaicznych Linuksach 
>>windach a także na bardziej wydumanych systemach typu OpenVMS. Dla mnie to 
>>jest całkiem przenośne.
> 
>>Platformy na których to nie działa można zapewne spokojnie olać. Nekrofilię 
>>zostawmy komu innemu.
> 
> No dobrze, nawet to załóżmy. Co to zmienia?

Że masz wygodne obiekty "naturalne" ale tylko w obszarze okna między 
proceseami. Że nie płacisz za wątki na kązdym kroku -- np. zwykłe operator 
new() działa szybciej (bo nie jest synchronizowane), std::tr1::shared_ptr 
takoż -- jest tak ze 2 razy szybszy. Jest lepsze rozdzielenie zadań. Do tego 
dochodzą różne narzędzia dostępne tylko dla procesów a nie dla wątków, 
narzędzia pozwalające lepiej zarządzić schedulingiem (z nietrywialnym 
zyskienm wydajności). W sumie? Masz kod równocześnie szybszy i mniej 
obawiasz się typowych dla wątków heisenbugów.


>>>>>Nie bez powodu stworzono normalny mechanizm wątków - gdyby komunikacja
>>>>>międzyprocesowa wystarczała, nikt by tego nie tworzył.
>>>
>>>>Kiedyś wydawało się, że tak będzie super. Bo przełączanie ciężkich 
>>>>kontekstów było wooolne, mechanizmy dzielonej pamięci bardzo ograniczone. 
>>>
>>>E tam ograniczone. Takie samo było jak jest teraz.
> 
>>No właśnie teraz jest całkiem nieźle.
> 
> Nie widzę akurat większych postępów w tej dziedzinie.

Patrz wyżej.


>>>>Tak miało być dużo szybciej.
>>>
>>>>Dziś takie rzeczy jak MPI pokazują że szybciej nie jest. Lepsze wsparcie dla 
>>>>pamięci dzielonej, np. poprzez memory mapped files
>>>
>>>I na czym polega owo "lepsze wsparcie" poza faktem, że jesteś w stanie tą
>>>pamięć zidentyfikować poprzez ścieżkę do pliku? Problemy z tworzeniem obiektów
>>>w takiej pamięci są dokładnie takie same, jak w shm.
> 
>>Na tym, że możesz wymusić zmapowanie pod określonym adresem. Takim samym w 
>>różnych programach.
> 
> Ależ taka możliwość istniała od samego początku w IPC SHM! Nie zawsze
> realizowalna, co prawda.

Dziś poprawiła się ta realizowalność. Kiedyś w ogóle obszar dzielalny był 
bardzo mały. Dziś jest lepiej.

>>>>pozwala na zrobienie 
>>>>wspólnego okna w przestrzeniach adresowych wielu procesów, gdzie wskaźniki 
>>>>zachowują się normalnie.
>>>
>>>A pamięć dzielona z IPC działała źle lub nie spełniała któregokolwiek z tych
>>>założeń?
> 
>>AFAIR może być kłopot ze zmapowaniem "na tej samej wysokości".
> 
> Ale to dotyczy wszystkich rozwiązań tego typu w równym stopniu.

Ale teraz nad tym można łatwiej zapanować (więcej jest dostępne).


>>>>Nie bardzo zależy. W Javie volatile jest ściśle wyspecyfikowane -- odowłanie 
>>>>do takiego pola oznacza na natywnej platformie wystosowanie odpwoiednich 
>>>>barier pamięci (acquire przed i release po odwołaniu). W GCC nic takiego nie 
>>>>ma. Jak architektura nie ma strict memory ordering to wszystko się rozjeżdża.
>>>
>>>Nie stawiałbym tutaj takich tez nt. gcc - chyba że wyraźnie tak piszą w
>>>specyfikacji tego kompilatora na każdą platformę.
> 
>>To pokaż mi taką platformę, gdzie w GCC odwołania do zmiennych volatile są 
>>owijane w bariery.
> 
>>Jak mi nie wierzysz, to spytaj się choćby Piotra Wyderskiego. On GCC używał 
>>na paru platformach
> 
> Nie mówię, że nie wierzę, ani nie twierdzę, że tak nie jest. Po prostu
> chciałbym zobaczyć jawną deklarację na ten temat (a swoją drogą, nic mi się
> nie udało ntt. znaleźć).

Bo AFAIR oni tego nigdzie nie robią. Trudniej jest znaleźć info że czegoś 
nie ma niż, że coś jest.


pzdr i wesołych świąt!

\SK
Technical Details
Message-ID: <fkobo3$mdl$1@bozon2.softax.pl>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!newsfeed.gazeta.pl!opal.futuro.pl!news.internetia.pl!newsfeed.tpinternet.pl!atlantis.news.tpi.pl!news.tpi.pl!bozon.softax.com.pl!not-for-mail
References: <fghgeo$spf$1@nemesis.news.tpi.pl> <fgo4c7$mtu$1@news.vectranet.pl> <20071106073039.433f4934@Vorago> <fgqn9m$74j$2@news.vectranet.pl> <618565031.20071107113041@pkierski.net> <fgt6sh$jov$1@news.vectranet.pl> <fgtb6j$nur$1@news.vectranet.pl> <fgv6ba$k14$1@bozon2.softax.pl> <fgvkne$u3b$1@news.vectranet.pl> <fh1tjd$dtt$1@bozon2.softax.pl> <fh2lj6$qkh$1@news.vectranet.pl> <fha3as$pap$1@bozon2.softax.pl> <fhaj8u$e02$1@news.vectranet.pl> <fhf09d$ohq$1@bozon2.softax.pl> <fhfi9l$640$1@news.vectranet.pl> <fhurmu$5d9$1@bozon2.softax.pl> <fhv020$8k1$1@news.vectranet.pl> <fi1bs4$nn3$1@bozon2.softax.pl> <fi27ds$gt1$1@kujawiak.man.lodz.pl> <fi458p$fmv$1@bozon2.softax.pl> <fi9ckc$2u5$1@kujawiak.man.lodz.pl> <fimb7n$80v$1@bozon2.softax.pl> <fj5k6j$r3e$1@kujawiak.man.lodz.pl> <fj68ei$vbo$1@bozon2.softax.pl> <fjmo4o$a5r$1@kujawiak.man.lodz.pl> <fjouia$gr3$1@bozon2.softax.pl> <fjpmln$o6q$1@kujawiak.man.lodz.pl> <fjtv6o$kc$1@bozon2.softax.pl> <fkea3q$lup$1@kujawiak.man.lodz.pl>

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!newsfeed.gazeta.pl!opal.futuro.pl!news.internetia.pl!newsfeed.tpinternet.pl!atlantis.news.tpi.pl!news.tpi.pl!bozon.softax.com.pl!not-for-mail
From: Sebastian Kaliszewski <s@get.it.off.to.reply.informa.pl>
Newsgroups: pl.comp.lang.c
Subject: Re: Ciemna strona C++
Date: Mon, 24 Dec 2007 14:38:28 +0100
Organization: Softax news server
Lines: 1190
Message-ID: <fkobo3$mdl$1@bozon2.softax.pl>
References: <fghgeo$spf$1@nemesis.news.tpi.pl> <fgo4c7$mtu$1@news.vectranet.pl> <20071106073039.433f4934@Vorago> <fgqn9m$74j$2@news.vectranet.pl> <618565031.20071107113041@pkierski.net> <fgt6sh$jov$1@news.vectranet.pl> <fgtb6j$nur$1@news.vectranet.pl> <fgv6ba$k14$1@bozon2.softax.pl> <fgvkne$u3b$1@news.vectranet.pl> <fh1tjd$dtt$1@bozon2.softax.pl> <fh2lj6$qkh$1@news.vectranet.pl> <fha3as$pap$1@bozon2.softax.pl> <fhaj8u$e02$1@news.vectranet.pl> <fhf09d$ohq$1@bozon2.softax.pl> <fhfi9l$640$1@news.vectranet.pl> <fhurmu$5d9$1@bozon2.softax.pl> <fhv020$8k1$1@news.vectranet.pl> <fi1bs4$nn3$1@bozon2.softax.pl> <fi27ds$gt1$1@kujawiak.man.lodz.pl> <fi458p$fmv$1@bozon2.softax.pl> <fi9ckc$2u5$1@kujawiak.man.lodz.pl> <fimb7n$80v$1@bozon2.softax.pl> <fj5k6j$r3e$1@kujawiak.man.lodz.pl> <fj68ei$vbo$1@bozon2.softax.pl> <fjmo4o$a5r$1@kujawiak.man.lodz.pl> <fjouia$gr3$1@bozon2.softax.pl> <fjpmln$o6q$1@kujawiak.man.lodz.pl> <fjtv6o$kc$1@bozon2.softax.pl> <fkea3q$lup$1@kujawiak.man.lodz.pl>
NNTP-Posting-Host: 83.18.189.42
Mime-Version: 1.0
X-Trace: nemesis.news.tpi.pl 1198503000 23046 83.18.189.42 (24 Dec 2007 13:30:00 GMT)
X-Complaints-To: usenet@tpi.pl
NNTP-Posting-Date: Mon, 24 Dec 2007 13:30:00 +0000 (UTC)
User-Agent: Mozilla Thunderbird 1.0.2 (X11/20050322)
X-Accept-Language: en-us, en
In-Reply-To: <fkea3q$lup$1@kujawiak.man.lodz.pl>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit