Dict, set, list!

Przy okazji niedawnego code review dostałem pytanie, czemu w skrypcie napisanym w Pythonie nie korzystam z obiektu typu set, tylko z dict. Chodziło o cache na kilka tysięcy elementów, odpytywany kilkaset tysięcy razy. Z przyzerowym hit ratio. Zdziwiłem się, bo kojarzyłem, że czytelna konstrukcja wykorzystująca in dla obiektu typu list

data = [x for x in range(1000)]
y = 1001
if y in data:
    print("Hit")

jest raczej wolna. Zwłaszcza w porównaniu z nieco mniej czytelnym wariantem z użyciem dict:

data = {x: True for x in range(1000)}
y = 1001
if data.get(y):
    print("Hit")

Odpisałem o co chodziło i usłyszałem, że przecież set jest szybki. Coś mi zaświtało. Bo niby set jest bardziej podobny w użyciu do listy, ale pod spodem ma parę ciekawych właściwości. Zresztą, gdy poprosimy LLM o optymalizację pod kątem szybkości, otrzymamy coś w stylu[1]:

data = {x for x in range(1000)} # Converted 'data' to a set
y = 1001
if y in data:  # Checking membership still works the same way
    print("Hit")

Różnice w czasie wykonania możemy zgrubnie i niezbyt elegancko sprawdzić w następujący sposób:

Jak już jesteśmy przy tego typu ciekawostkach. A co jeśli mamy w cache ciągi znaków i chcemy sprawdzić, czy nasz ciąg znaków nie kończy się jednym z ciągów z cache? LLM poproszony o optymalizację znowu podpowiada, że lepszy jest set. Ale nieoczekiwanie sugeruje też wykorzystanie regexpów. I co? Ku mojemu zaskoczeniu regexp w stylu

pattern = re.compile("("+"|".join(our_set)+")"$")
return bool(pattern.search(tested_value))

okazuje się najszybszym rozwiązaniem! Nie to, że uważam regexpy za szczególnie wolne, co to, to nie. Oczywiście pattern wykonujemy raz, nie dla każdej testowanej wartości.

Dalsza lektura:
O’reily High performance Python Dictionaries and Sets

[1] Tak, różnica niezbyt rzuca się w oczy przy takim zapisie. Mało widać różnicę między dict a set. Kiedyś już o tym wspominałem. Czytelniejszy zapis – którego chyba nikt nie używa – tamże.

Bieganie i rower 2023 – podsumowanie

Bieganie w roku 2023 zacząłem wcześnie, bo już 8 stycznia. Zupełnie tak samo jak w zeszłym roku! Biegałem nawet regularnie, więc w maju osiągnąłem poprzednią formę i zacząłem poprawiać wyniki. Biegi w okolicach 8 km. Szło dobrze, zastanawiałem się nawet ile przebiegnę w tym roku i czy będzie nowy rekord. Niestety zaraz dowiemy się, czemu się nie udało. I nie pomogło nawet szalone firmowe wyzwanie dwa miesiące przed świętami, w którym już zupełnie na ludzie dorzuciłem w nim 44 km. Byłoby więcej, ale przeszkodziło i zdrowie – przeziębienie, i aktywna końcówka roku pod innymi względami.
Bieganie 235 km, 38 aktywności, 24h w ruchu.

Biegało mi się tak dobrze, że postanowiłem dołożyć rower. Uruchomiłem go w tym roku bardzo późno, bo dopiero 30 czerwca. I to był błąd. Rower zupełnie skanibalizował bieganie. Tym bardziej, że gdy jest upał, to dużo przyjemniej jechać rowerem, niż biec. Zacząłem jeździć nie tylko komunikacyjnie, ale i rekreacyjnie trasy po ok. 30 km. Wada? Nie było czasu na bieganie. I jakoś forma biegowa siadła.
69 aktywności, 411 km, 33h w ruchu.

Jak widać, dobry początek roku jeszcze o niczym nie świadczy i nie można dzielić skóry na niedźwiedziu. Rower nie zastąpi biegania. Miał być progres, był regres. Chociaż jak sprawdziłem poprzednie parę lat, a nie tylko 2022, to w sumie bez dramatu.

Ale jest i sukces. Pierwszy bieg w styczniu, bieganie zimą na początku roku. Oraz trochę pobiegane pod koniec roku. Ostatni(?) bieg 17 grudnia. Czyli udało się biegać przez cały rok.

Hej naprzód marsz – wolontariat

Od zeszłego roku w firmie mamy dodatkowy dzień wolny. Znaczy niezupełnie wolny. I pod warunkiem. Warunkiem jest wykorzystanie tego dnia na wolontariat. Jeśli nie zostanie wykorzystany w danym roku – przepada.

Pomysł na oko fajny, o ile ktoś udziela się już w tej formie. Dla kogoś takiego jak ja, który w dni powszednie nie udziela się – pomysł teoretycznie fajny. Z wolontariatu przychodził mi do głowy jedynie finał WOŚP, który odbywa się w dzień wolny. Do tego pewnie musiałbym się zorientować jakie papierki są wymagane i czy fundacja je wystawia. Nic więc dziwnego, że w zeszłym roku dzień mi przepadł.

Szczęśliwie głosy pracowników o tym, że przydała by się inspiracja, albo i podsunięcie stosownego zajęcia pod nos, zostały wysłuchane. Ekipa, która znalazła i wspierała potrzebującą fundację już w zeszłym roku, poszła w tym roku szerzej i zorganizowała wolontariat dla szerszego grona chętnych.

Organizacja na piątkę z plusem – wystarczyło określić w którym terminie chcemy pracować i się zapisać. Oprócz narzędzi i materiałów do pracy, papierkologii, załatwiony został także transport w postaci arkusza do wspólnego przejazdu autami. Czyli wszystko, co potrzeba.

Wolontariat miał miejsce w stadninie koni. Do wykonania było malowanie stajni oraz grodzenie nowych wybiegów. Pogoda dopisała, poza tym wolałem zrobić coś, gdzie się zmęczę a nie znowu malowanie. Bo w życiu trochę się namalowałem i mogę powiedzieć, że umiem – ach te remonty i remonciki w domu…

Ostatecznie, po początkowych zawirowaniach, wyklarowały się ekipy kopiące, koszące, mierzące. Po przerwie na posiłek regeneracyjny i montażu pierwszej części ogrodzenia pojawiło się nowe zadanie – okablowanie elektrycznego pastucha. Bardzo mi się ono spodobało, bo z elektrycznymi pastuchami nie miałem w życiu do czynienia. Zresztą, jak to zamontować, to chyba nikt nie wiedział. Na szczęście były istniejące ogrodzenia na wzór.

Dowiedziałem się, że elektryczny pastuch składa się z generatora, podającego napięcie na płot. Nie ma zamkniętego obwodu, nie ma plus i minus – wyładowanie następuje do ziemi, tam zresztą podłącza się „drugi kabel” od generatora. A całe ogrodzenie to jeden wielki, wspólny element pod napięciem. Inne ciekawe rzeczy – napięcie w naszym przypadku to jakieś 6000V. Istnieją dedykowane narzędzia do pomiaru, ale działanie można sprawdzić i ręką. Nie jest groźne, jest nieco nieprzyjemne. I jeszcze ważna rzecz – pastuch wysyła impulsy, więc nie „kopie” cały czas, krótkie dotknięcie nie powie prawdy, czy jest załączony.

Po pracy mieliśmy relaks przy grillu. Ogólnie bardzo fajna impreza, w doskonałej atmosferze. Fajnie, że pogoda dopisała, choć mogło być nieco chłodniej. Niemal cały dzień na łące, bez cienia może być męczący sam w sobie. Na szczęście było mnóstwo wody w butelkach i były podpowiedzi wcześniej, by wziąć czapki i krem ochronny.

Opisuję całość, bo w tego typu grupowym wydaniu wolontariat może z powodzeniem służyć jednocześnie za integrację. Zorganizowanie grilla na istniejącej infrastrukturze jest tanie, ludzie spędzają ze sobą dużo czasu robiąc zupełnie inne rzeczy, niż w pracy. Cel jest fajny bo i daje satysfakcję – widoczna, wykonana praca, i pomaga się potrzebującym. W porównaniu z dedykowanymi wyjazdami integracyjnymi to pewnie jakieś śrubki, tym bardziej, że firma pewnie też może to jakoś rozliczyć. Choć nie wiem, nie jestem księgowym. Oczywiście nie zastąpi to typowych integracji w każdym przypadku, tym bardziej, że nie każdy może/chce pracować fizycznie, ale warto rozważyć naśladowanie.