Ahrefs.com – porządki na blogu

Jakiś czas temu założyłem konto w serwisie ahrefs.com. Jest to porządnie wyglądający serwis służący SEO. Zależało mi na site audit, w szczególności na sprawdzeniu błędów linkowania. Mogłem co prawda użyć narzędzia w stylu linkchecker, ale jakoś i więcej opcji, i prostsze w użyciu. Poza tym, ahrefs.com daje narzędzia do śledzenia słów kluczowych, popularności stron itp. Stwierdziłem, że popatrzę, choć jest tego za dużo jak na moje potrzeby. Nawet w wersji darmowej.

Cieszę się, że to zrobiłem. Okazało się, że niewielka część tytułów wpisów została źle zaimportowana podczas migracji z Blox. Czyli linki w treści były po staremu, ale tytuły zostały zmienione. Chyba Blox był bardziej liberalny jeśli chodzi o znaki w tytule. A może to po prostu problem z kodowaniem pl-znaków? W każdym razie musiałem zmienić linkowanie w kilkunastu wpisach, łącznie duże kilkadziesiąt miejsc. Czasem przy okazji robiłem i inne porządki. Zdarzają się bowiem pewne zaszłości, które może niekoniecznie łatwo zauważyć, ale nie są już potrzebne. Czyli bez sensu zużywają zasoby.

Gdyby ktoś zdecydował się pójść w moje ślady, polecam wykluczyć ze skanowania strony tagów, kategorii itp. Niczego nie wnoszą, bo jedynie powielają treść z wpisów, a one służą jedynie za agregaty wpisów. Za to brak ich wykluczenia powoduje błyskawiczne zużywanie quoty. Na szczęście ahrefs.com pozwala na wykluczenie URLi ze skanowania przy pomocy wyrażenia regularnego (czyt.: regexp).

Przyznaję, że nieco się rozochociłem, więc zamierzam sprawdzić także linki wychodzące do stron zewnętrznych. A może i stary blog się załapie na porządki? Oczywiście nic nagle, raczej zabawa do kawy raz w tygodniu. Przy czym tam to już raczej w grę wchodzi zabawa z użyciem sed.

Sonoma

O ile poprzednia aktualizacja była nudna, to ta zdecydowanie nudna nie jest. Niestety. Parę dni temu zaktualizowałem macOS do najnowszej wersji Sonoma i… jest wesoło. Przede wszystkim mamy nową tapetę czy też wygaszacz ekranu. Animowany. Zapytał, czy przełączyć przy instalacji, a ja się nieopatrznie zgodziłem. Niestety bardzo widoczny staje się wtedy notch. Zdecydowanie lepiej sprawdza się – przynajmniej u mnie – tapeta z ciemnym tłem u góry.

Na to, że nie działa hidutil byłem przygotowany. Szczęśliwie okazało się, że teraz prawe option i cmd pozwalają wpisywać pl-znaki. Czyli albo coś tam jednak działa, albo inne ustawienie wzięło górę. W każdym razie da się żyć. Mapowania tyldy i tak nie używałem. Braku normalnego wprowadzania pl-znaków bym nie zniósł.

Znajomi pytają, czy po upgrade do Sonomy miga mi ekran. Tak, ale naprawdę rzadko i minimalnie. Nie wiem czy bym zauważył, gdyby nie zapytali. Chyba podrzucę im poradę z usuwaniem profili kolorów.

W każdym razie macOS Sonoma to bardzo słaba, problematyczna wersja. Chyba najsłabsza aktualizacja w historii, choć mnie szczęśliwie problemy dotykają jedynie minimalnie.

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.