Efektywne struktury danych: Sets i Maps

Optymalizacja kodu w Javie

Pavlos Kosmetatos

Lead Engineer @Wealthyhood

Zastosowanie złożoności czasowej i pamięciowej

Znamy już złożoność czasową i pamięciową!

Jak wykorzystać tę wiedzę do pisania wydajniejszego kodu?

Przez wybór właściwej struktury danych!

Optymalizacja kodu w Javie

System zarządzania użytkownikami

  • Budujemy system zarządzania użytkownikami

  • Musimy sprawdzić, czy dany użytkownik istnieje

  • Użycie listy: złożoność $O(n)$

public boolean usernameExists(ArrayList<String> users, String newUsername) {
    for (String username : users) {
        if (username.equals(newUsername)) {
            return true;
        }
    }
    return false;
}
Optymalizacja kodu w Javie

Sets

  • Kolekcja unikalnych elementów z szybkim wyszukiwaniem
  • Średnia złożoność $O(1)$ dla dodawania, usuwania i sprawdzania obecności elementu

Ulepszone rozwiązanie systemu zarządzania użytkownikami:

public class UserRegistry {
    private HashSet<String> users = new HashSet<>();

    public boolean userExists(String username) {
        return users.contains(username); // O(1) average time
    }
}
Optymalizacja kodu w Javie

Maps

  • Jak słownik: słowo (klucz) -> definicja (wartość)
  • HashMap: średnia złożoność $O(1)$ dla operacji
public class UserCache {
    private HashMap<String, UserProfile> userProfiles = new HashMap<>();

    public UserProfile getUser(String username) {
        return userProfiles.get(username);  // O(1) average time
    }
}
Optymalizacja kodu w Javie

Metoda hashCode

  • Źródło szybkości -> hashCode()
  • W przykładzie z ArrayList nie znaliśmy indeksu szukanej nazwy użytkownika
  • Metoda hashcode() przekształca obiekt w indeks, pod którym można go znaleźć
  • Przykład: pavlos.2020 -> 35189

pavlos.2020 przetworzony przez hashcode, wynik: 35189

Optymalizacja kodu w Javie

Indeksowanie elementów

  • HashMap i HashSet mają wewnętrzną tablicę
  • Podczas dodawania elementu:
    • Java wywołuje hashCode() na elemencie, zwracając liczbę całkowitą
    • Następnie stosuje modulo, aby uzyskać numer kubełka

Przykład:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

"optimizingCodeInJava" -> 1406313774 // Implemented by Java
1406313774 % 16 = 14 <- that's our bucket!
Optymalizacja kodu w Javie

Kolizje

  • Gdy więcej niż jeden element trafia do tego samego kubełka
    • Nazywamy to kolizją
  • LinkedList dla kubełka
  • Dlatego mówimy $O(1)$ średnio
Optymalizacja kodu w Javie

Warto zapamiętać

Wybór struktury danych przypomina dobór odpowiedniego narzędzia – młotek (ArrayList) świetnie sprawdza się przy gwoździach, ale nie przy śrubach (gdzie lepszy będzie Set).

Narzędzia

Optymalizacja kodu w Javie

Czas na ćwiczenia!

Optymalizacja kodu w Javie

Preparing Video For Download...