Powrót do strony głównej

Tablice PHP bezpieczne typowo: +4x prędkości

Artykuł analizuje optymalizacje biblioteki sbwerewolf/language-specific: przyspieszenie 4-krotne, porównanie z wplake/typed. Przedstawiono benchmarki, przykłady kodu łańcuchowego API i nowe możliwości jak niemutowalność.

PHP: tablice bezpieczne typowo 4 razy szybsze
Advertisement 728x90

Typobezpieczny dostęp do tablic w PHP: 4-krotne przyspieszenie bez utraty czytelności

Biblioteka sbwerewolf/language-specific w wersji 10.4.5 osiągnęła 4-krotne przyspieszenie w porównaniu do wersji 8.4.1. Odstaje teraz od wplake/typed (1.2.2) tylko o czynnik 2×. Pierwsze podejście używa ścieżek tekstowych, drugie — łańcuchów metod do nawigacji po strukturze danych.

Przykład z wplake/typed:

use Wplake\Typed\Typed;

$response = file_get_contents(
    'https://geocode-maps.yandex.ru/1.x/?apikey=d3893dc1-c136-4084-b9c-4db26b00463e&geocode=Mohammed+Bin+Rashid+Boulevard+1&lang=en_US&format=json'
);

$object = json_decode(json: $response, associative: true, flags: JSON_THROW_ON_ERROR);

$path = 'response.GeoObjectCollection.featureMember.0.GeoObject.metaDataProperty.GeocoderMetaData.Address.formatted';

// wartość z fallbackiem
$val = Typed::string($object, $path, 'Adres nie znaleziony');
var_dump($val);
/*
string(77)
"1, Mohammed Bin Rashid Boulevard, Downtown Dubai, Dubai, United Arab Emirates"
*/

$isReal = Typed::stringOrNull($object, $path) !== null;
var_dump($isReal);
/* bool(true) */

Analogiczna funkcjonalność w sbwerewolf/language-specific:

Google AdInline article slot
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;

$response = file_get_contents('https://geocode-maps.yandex.ru/1.x/?apikey=d3893dc1-c136-4084-b9c-4db26b00463e&geocode=Mohammed+Bin+Rashid+Boulevard+1&lang=en_US&format=json');

$object = json_decode(json: $response, associative: true, flags: JSON_THROW_ON_ERROR);
$data = new AdvancedArrayFactory()->makeAdvancedArray($object);
$formatted = $data
    ->pull("response")
    ->pull("GeoObjectCollection")
    ->pull("featureMember")
    ->pull()
    ->pull("GeoObject")
    ->pull("metaDataProperty")
    ->pull("GeocoderMetaData")
    ->pull("Address")
    ->get("formatted")
    ->default("Adres nie znaleziony");
$val = $formatted->str();
var_dump( $val);
/* 
string(77)
"1, Mohammed Bin Rashid Boulevard, Downtown Dubai, Dubai, United Arab Emirates"
*/
$isReal = $formatted->isReal();
var_dump( $isReal);
/* bool(true) */

Testy wydajnościowe

Testy przeprowadzono na przypadkach rzeczywistych zadań: parsowanie JSON w scenariuszu „happy path”, brakująca ścieżka, sprawdzanie istnienia elementu oraz typowanie wartości.

| Przypadek użycia | 8.4.1 (wcześniej) | 10.4.5 (teraz) | 1.2.2 (wplake/typed) |

|------------------|-------------------|----------------|----------------------|

Google AdInline article slot

| Parsowanie JSON – happy path | 29,210 µs/op | 6,467 µs/op | 3,013 µs/op |

| Parsowanie JSON – brakująca ścieżka | 18,716 µs/op | 5,987 µs/op | 1,766 µs/op |

| Czy element istnieje? | 27,237 µs/op | 6,277 µs/op | 2,863 µs/op |

Google AdInline article slot

| Pobranie typu wartości | 28,581 µs/op | 6,740 µs/op | 2,966 µs/op |

| Pobranie wartości bez zmian | 30,395 µs/op | 6,558 µs/op | 3,015 µs/op |

| Pobranie wszystkich wartości skalarnych | 5,897 µs/op | 1,878 µs/op | nieobsługiwane |

| Pobranie wszystkich tablic | 7,136 µs/op | 2,431 µs/op | nieobsługiwane |

Nowe możliwości w wersji 10.4.5: pobieranie wszystkich wartości skalarnych i wszystkich tablic — niedostępne w wplake/typed.

Kluczowe zmiany w architekturze

  • Niezmienialność CommonValue: klasa stała się niemutowalna — eliminuje się modyfikacje po ustawieniu wartości domyślnej.
  • Determinizm pull(): przy pobieraniu elementu z tablicy zawsze zwracany jest pierwszy element — usunięto losowość.
  • Uproszczenie API: usunięto pomocnicze klasy; cała logika działa w jednym, spójnym łańcuchu.

Zgodność wsteczna została formalnie naruszona przez aktualizację majorową (8.4.1 → 10.4.5), ale publiczne API pozostaje identyczne. Kod klientów nie wymaga żadnych modyfikacji.

Nowe metody i funkcje

Pełna lista metod łańcuchowych:

  • pull(string $key) — pobiera zagnieżdżony element,
  • pull() — pierwszy element tablicy (deterministycznie),
  • get(string $key) — pobiera wartość z weryfikacją istnienia,
  • default(mixed $fallback) — wartość domyślna przy braku elementu,
  • str() — konwersja do stringa,
  • isReal() — sprawdza, czy wartość istnieje.

Przykład kompleksowego zastosowania do przetwarzania odpowiedzi API o niestabilnej strukturze.

Co jest ważne

  • 4-krotne przyspieszenie względem wersji podstawowej, odstaje od lidera tylko o 2×.
  • Zachowano czytelność łańcuchów metod zamiast nieczytelnych ścieżek tekstowych.
  • Dodano unikalne funkcje: zbieranie wszystkich wartości skalarnych i tablic.
  • Niezmienialność i determinizm zwiększają niezawodność kodu.
  • Idealne dla programistów średnio- i seniorowych: bezpieczeństwo typów + wysoka wydajność.

— Editorial Team

Advertisement 728x90

Czytaj dalej