Skocz do zawartości
Auberon

Niskiej jakości kod w zadaniu rekrutacyjnym

Rekomendowane odpowiedzi

46 minut temu, Bono[UG] napisał:

Przede wszystkim shared_ptr.

To błagam, jasno to specyfikuj. Ktoś to bezkrytycznie przeczyta i dojdzie do wniosku, że unique_ptr ma jakikolwiek mierzalny wpływ na wydajność aplikacji :P

Wiem, że "there are no zero cost abstractions" (must watch, by the way), ale jeżeli gdzieś widać "narzut" unique_ptr, to jest tam dużo poważniejszy problem niż użycie unique_ptr.

49 minut temu, Bono[UG] napisał:

Musiałbyś mi coś podrzucić do poczytania, bo nie ukrywam, za bardzo siedzę w erze sprzed C++11 i nowszych (cóż, niezbyt nowoczesne platformy do załadowania oprogramowania).

No część z tego znasz na pewno, tylko może nie po nazwach ;) I to wszystko w starożytnych C++ już było: https://godbolt.org/z/hv1Yor31G

Z miejsca nie zarekomenduję konkretnych czytanek. cppreference jest, ale nie jest zbyt lekkostrawne - bo o ile wpisy o RAII i std::alokatorach jeszcze są do przeżycia, to te o lifetime i new expression to wręcz prawnicza interpretacja standardu. Już prędzej prezentacje z konferencji branżowych.

Oczywiście placement new jest raczej do opakowanego użytku, bo wciąż jest tylko narzędziem do manualnego zarządzania lifetime obiektu. A na przykładzie wyżej widać wyraźnie co się (nie) dzieje jak accept rzuca :P

Mniej więcej to robi std::vector pod spodem (tyle że opisane alokatorem). Alokuje raz (na jakiś czas) storage, a potem woła odpowiednik placement new przy dodawaniu. Nie może alokować przez new T[x], bo poza pozyskaniem storage skonstruowałoby od razu x elementów.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
15 godzin temu, MitycznyJeż napisał:

No część z tego znasz na pewno, tylko może nie po nazwach ;) I to wszystko w starożytnych C++ już było: https://godbolt.org/z/hv1Yor31G

Muszę to przegryźć jak będę przytomniejszy.

Pewnie jak wiele innych rzeczy, używam ale nie mam świadomości, że się to jakoś nazywa. Kiedyś na szkoleniu przy wzorcach, prowadzący właśnie takie coś powiedział. Dodał też istotną rzecz, że nie ma sensu na siłę dopasowywać wzorca.

Jeżeli dobrze rozumiem mechanizm, to zyskam na braku wołania systemu o pamięć ale muszę ją sam organizować i pilnować. Będzie miało swoje zastosowanie ale z drugiej strony czym się różni w praktyce od tej mojej stworzonej puli obiektów na początku i żonglowania wskaźnikami.
Na razie przychodzi mi tylko do głowy eliminacja funkcji wstawiającej nowe dane do obiektu, mniej linii kodu, bo konstruktor robi praktycznie to samo.

 

A z ciekawostek na jakie można trafić w starym kodzie.
Mam bibliotekę do obliczeń na wektorach i macierzach, podstawy pamiętające jeszcze fortrana. No i ostatnio przyszło mi się przekompilować na 64b, poszło ale program bardzo szybko wywalał się z błędem o złym rozmiarze jakiegoś argumentu w funkcji. W środowisku 32b wszystko działało bez problemu.
Trochę czasu mi zajęło dogrzebanie się co i gdzie się dzieje. Oczy zrobiłem jak 5zł jak doszło do mnie co się tam wyprawia. Wyglądało to skrótowo tak:

typedef long int integer; //zapewnienie kompatybilności z kodem fortranowym


funkcja1(int a)
{
	...
	funkcja2(&a);
	...
}

funkcja2(integer *b){...}

W 32b wszystko ok, bo int i long mają po 4B. W 64b już się rozjeżdża, bo int nadal 4B ale long ma już 8B. A tutaj ktoś ochoczo rzuca wskaźnikiem do inta na wskaźnik do longa :E

Przegrzebałem się przez historyczne repozytoria (pamięta ktoś jeszcze cvs-a?), żeby zobaczyć kto takie zło popełnił. Wyszło mi, że ta biblioteka ma już około 20 lat. Smaczku dodaje znajdujący się tam readme, gdzie było jak byk, że przy kompilacji na 64b tego typdefa będzie trzeba poprawić, no ale kto by czytał readme ;)

Jeżeli ktoś się bawi w skakanie po różnych platformach i środowiskach, to polecam ścisłe typowanie rozmiarów zmiennych: int32_t, uint64_t itd.
https://en.cppreference.com/w/cpp/types/integer

  • Like 1

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
4 godziny temu, Bono[UG] napisał:

Pewnie jak wiele innych rzeczy, używam ale nie mam świadomości, że się to jakoś nazywa. Kiedyś na szkoleniu przy wzorcach, prowadzący właśnie takie coś powiedział. Dodał też istotną rzecz, że nie ma sensu na siłę dopasowywać wzorca.

Dokładnie - wzorce to i tak po prostu spisane praktyki, na które bardzo często samemu się wpada próbując rozwiązać dany problem.

4 godziny temu, Bono[UG] napisał:

Jeżeli dobrze rozumiem mechanizm, to zyskam na braku wołania systemu o pamięć ale muszę ją sam organizować i pilnować. Będzie miało swoje zastosowanie ale z drugiej strony czym się różni w praktyce od tej mojej stworzonej puli obiektów na początku i żonglowania wskaźnikami.

W przypadku użycia placement new - no, niewiele :E Nie tyle rekomenduję ten mechanizm, co zwracam uwagę na odrębność dwóch etapów potrzebnych, by zainstniał obiekt.

Odnosiłem się jedynie do przekonania, że tworzenie obiektów oznacza alokację, a więc i potencjalnie nieakceptowalny koszt. Wszystko zależy od tego gdzie i jak je tworzymy.
Najlepiej na stosie oraz bezpośrednio jako member w innych klasach, dopiero w uzasadnionych przypadkach rozpatrywać stertę i/lub ręczny placement.

Nie ma przeciwwskazań, by używać RAII i pakować logikę posiadającą pary otwórz-zamknij zablokuj-odblokuj itp. w klasy nawet w środowiskach mocno ograniczonych, gdzie nie ma runtime'u, który by dostarczał funkcje alokujące czy wyjątki.

4 godziny temu, Bono[UG] napisał:

Wyglądało to skrótowo tak:

C-style rzutowania też tam były, co by kompilator ostrzeżeniami nie zawracał gitary? :D

Edytowane przez MitycznyJeż

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
2 godziny temu, MitycznyJeż napisał:

C-style rzutowania też tam były, co by kompilator ostrzeżeniami nie zawracał gitary? :D

Przypuszczam, że takie są, bo nikt wtedy nie pisał w c++ ;)

Trochę lat wstecz (z 10?) to miałem okazję szukać czegoś na dyskietkach (na szczęście już 3,5" i jeszcze miałem napęd w komputerze ;) ), a kod okazał się pisany w Pascalu :E

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
Teraz, Bono[UG] napisał:

Trochę lat wstecz (z 10?) to miałem okazję szukać czegoś na dyskietkach (na szczęście już 3,5" i jeszcze miałem napęd w komputerze ;) ), a kod okazał się pisany w Pascalu :E

Patrząc wstecz ten język miał parę dziwnych rozwiązań. Na przykład bez stosowania specjalnych opcji kompilatora, standardową reakcją na wszelkie wyjątki było zakończenie programu pomimo tego, że na poziomie pisanego kodu można było normalnie te wyjątki łapać.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
W dniu 12.01.2022 o 22:07, Bono[UG] napisał:

Przypuszczam, że takie są, bo nikt wtedy nie pisał w c++ ;)

Trochę lat wstecz (z 10?) to miałem okazję szukać czegoś na dyskietkach (na szczęście już 3,5" i jeszcze miałem napęd w komputerze ;) ), a kod okazał się pisany w Pascalu :E

A w czym tu był problem skoro to wystarczy ze sobą zlinczować?

W dniu 12.01.2022 o 22:15, Radar28 napisał:

Patrząc wstecz ten język miał parę dziwnych rozwiązań. Na przykład bez stosowania specjalnych opcji kompilatora, standardową reakcją na wszelkie wyjątki było zakończenie programu pomimo tego, że na poziomie pisanego kodu można było normalnie te wyjątki łapać.

Pascal czy Delphi?

Pascal był strukturalny a Delphi to Object Pascal

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
W dniu 9.01.2022 o 23:02, Bono[UG] napisał:

Co rozumiesz pod pojęciem zwykłych obiektów, a co pod wskaźnikiem?
Ja pod tymi wskaźnikami mam obiekty. Po prostu na starcie programu alokuję sobie odpowiednią pulę takich obiektów i potem operuję już tylko na wskaźnikach do niech.

Kwestia konkretnego zastosowania, jakbym miał co chwila tworzyć i niszczyć tysiące obiektów, to zajmie to więcej czasu niż przekazanie wskaźnika do obiektu i szybkie wyzerowanie danych memset-em (nie każda struktura/obiekt się do tego nada, to też trzeba uwzględnić).

Fajnie się o takim czystym obiektowym oprogramowaniu opowiada jak się nie działa w reżimie czasu (ja nie działam jeszcze w real time ale dosyć mocno się do takich wymagań zbliżam) i na ograniczonych zasobach (ile ich mogę wziąć dla siebie, no i realnie ile procek i pamięć wydolą). Przekazanie wskaźnika, zerowanie danych jest szybsze niż tworzenie i niszczenie obiektów, bo nie wymaga operacji alokacji/dealokacji pamięci, nie trzeba wołać funkcji systemowych zarządzających pamięcią, które dadzą dodatkowe opóźnienia (niekoniecznie przewidywalne).

Łatwo też się takie akademickie podejście stosuje jak operuje się na niewielkich zbiorach danych. Kilka, kilkanaście, kilkaset obiektów, to jest pryszcz. Mi się zdarza operować na kilkudziesięciu czy nawet kilkuset tysiącach (pi*drzwi kilkanaście GB/s, choć może ciut przesadzam), ot taki zasobożerny algorytm (drzewo hipotez do zbudowania i rozpatrzenia każdej gałęzi) i dane na jakich pracuję (jeden obiekt, to więcej niż kilka zmiennych).

Znowu, kwestia zastosowania.

U siebie wiem, że koniec działania programu, to wyłączenie systemu/komputera lub jego reset. Nie muszę się bawić w pisanie fragmentu programu, który ładnie wszystko pozamyka.

zamiast

obiect * a = new obiect(jakiś_parametr);

stosować

obiect a(jakiś_parametr);

albo wręcz stosować dziedziczenie i listę inicjalizacyjną konstruktora

class obiect2 : obiect
{
public:
obiect2(unsigned jakiś_parametr) : obiect(jakiś_parametr) {}
}

i to w zasadzie jest "cytat" z kodu jaki dostałem

nie jestem pewien czy się dobrze zrozumiemy :P

W dniu 9.01.2022 o 03:34, Karister napisał:

Sam kod nie zarabia. Potrzeba marki, biznesplanu, marketingu, pozycji na rynku, funduszy, a także sporo szczęścia. Do tego skoro ta firma zatrudnia, to jest lata do przodu względem startupu - mają klientów i pozycję na rynku.

Co jeśli nie jest to zatrudnienie tylko forma współpracy oparta o umowy cywilno-prawne?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
2 godziny temu, Auberon napisał:

Co jeśli nie jest to zatrudnienie tylko forma współpracy oparta o umowy cywilno-prawne?

Nie widzę jakiegokolwiek związku formy zatrudnienia z zaawansowaniem biznesu. Umowy cywilno-prawne w IT to tylko i wyłącznie unikanie danin. W umowie będzie tuzin stron o zakazie konkurencji z wysokimi karami.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
W dniu 15.01.2022 o 21:23, Auberon napisał:

Pascal czy Delphi?

Pascal był strukturalny a Delphi to Object Pascal

Pascal. Jeśli dobrze pamiętam, to dokładnie Borland Pascal 5.5.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się

  • Ostatnio przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

  • Tematy

  • Odpowiedzi

    • Cały czas na tym samym kablu jedziesz? A np. wyciągnięcie i ponowne włożenie kabla nie likwiduje problemu?
    • Jak oni te pasty nakładają? Ręcznie czy maszynowo? Bo jak miałem 970 strixa, to po chyba 4-5 latach od kupna uznałem że wymienię pastę, bardziej z ciekawości jak to się robi, niż ze wzrostu temperatur, jak ściągnąłem chłodzenie, to sobie myślę WTF? Pasta tak walnięta jakby ktoś to po kilku głębszych robił, nie wiem ale połówka rdzenia była bez pasty  może to tak miało być, bo wsumie jeden jedyny raz wymieniałem pastę na gpu.
    • Nie ma czegoś takiego... ta zgoda podobno istniała już kilka razy w ciągu kilku miesięcy, a jednak... Obecnie Partia Republikańska w większości to opłacane przez Putina pionki, mniejszość to ta, która chce pomóc Ukrainie. Do tego masz karierowiczów, którzy zrobią wszystko(Johnson, który bez przyzwolenia Trumpa nie kiwnie palcem). Trump jest najważniejszym politykiem po prawej stronie w USA i to on decyduje o kształcie i kierunkach polityki Partii Republikańskiej. Właśnie z tego powodu rozdzielili te pakiety pomocowe, bo okazało się, że część demokratów nie chciała poprzeć pomocy dla Izraela(morderstwa osób cywilnych w Gazie), a tym samym dla Ukrainy i zrobił się kłopot. Teraz pomoc dla Izraela przejdzie, a pomoc dla Ukrainy zostanie uwalona, jeśli w ogóle zostanie poddana pod głosowanie. Reagan przewraca się w grobie, bo jest totalnie niezrozumiałe czym stała się prawica w USA i czyich interesów broni.    Kiedy Russia Today wchodzi za mocno... "Ukraińscy naziści, którzy powinni oddać Rosji część swojego terytorium". Tak wygląda dzisiaj przeciętny Republikanin, który przedstawia narrację i propagandę rosyjską. Przerażające do czego mogą doprowadzić pieniądze i głosowanie na populistów. To pokazuje jak mocne wpływy ma Rosja w USA(ale to już wiadomo oficjalnie po raporcie dotyczącym wyborów i wygranej Trumpa).
    • To już druga osoba bodajże w tym temacie z tym samym modelem i po własnej aplikacji pasty taka duża różnica, gwarancji nie trzeba żegnać jak przyrosty są tak fajne to warto to zrobić, jak jest plomba na którejś śrubie to można zamówić i nakleić jeżeli np suszarka + żyletka nie dały rady lub w ogóle ktoś robi dziurę w plombie od razu  Chwile temu zamawiałem z alledrogo do xfx https://allegro.pl/oferta/5x-naklejki-gwarancyjne-asus-msi-palit-xfx-evga-gigabyte-zotac-15362612792
    • Dane CFM z opakowań producentów nie można porównywać między nimi, a najlepiej kompletnie na te dane nie patrzeć. Nie dość, że nie ma żadnego ogólne standardu względem którego dokonywane są te pomiary, więc każdy producent mierzy jak uważa, to dodatkowo zarówno te dotyczące przepływu jak i ciśnienia są dokonywane przy skrajnych i nierealnych sytuacjach. Na przykład w przypadku ilości przepchniętego powietrza mogą być stosowane kilkudziesięciocentymetrowe tunele z "prostownikami przepływu" na końcu którego znajduje sie wentylator i po przeciwnej stronie przyrząd do pomiaru, czyli coś czego nikt w domowym komputerze nie zastosuje przez co taki wynik jest niestosowalny w praktyce dla wentylatora zamontowanego bezpośrednio na radiatorze (czy to od wieży chłodzenia czy układu cieczą) lub kratce obudowy. Zostają tylko praktyczne testy jak np. TechPowerUP czy HWCooling.net lub takie przy stałej metodologii dla wszystkich śmigieł jak np. Cybenetics. W takim przypadku będziesz miał miarodajne wyniki. Nie potrzebujesz takiej przejściówki dopóki gniazdo do którego wpinasz 4 pinową wtyczkę nie jest blokowane plastikiem z boku w którym wtyczka by wystawała (a jeżeli blokuje to możesz próbować tę blokadę usunąć). Rozstaw pinów w wentylatorze 2, 3 i 4 pinowym jest teoretycznie identyczny, bo dwa pierwsze piny to kolejno uziemienie i napięcie, kolejny to pomiar obrotów i ostatni czwarty to pin do sterowania PWM. Wentylator 2 i 3 pin można sterować tylko poprzez zmianę napięcia pracy, a dla wentylatora PWM nie ma teoretycznie znaczenia czy steruje się go sygnałem czy napięciem, tak długo jak jego sama konstrukcja nie przeszkadza w sterowaniu jego obrotami poprzez zmianę napięcia zamiast sygnałem modulacyjnym (jak np. nie powinno się robić w przypadku łożysk magnetycznych jak w wentylatorach Phanteks T30 lub Corsair ML120 czy konstrukcjach Sunona MagLev).
  • Aktywni użytkownicy

×
×
  • Dodaj nową pozycję...