2015-09-17 12 views
5

PHP mają wewnętrzną strukturę danych o nazwie smart string (smart_str?), W której przechowują zarówno długość, jak i rozmiar bufora. Oznacza to, że więcej pamięci niż długość ciągu jest przydzielana w celu poprawy wydajności konkatenacji. Dlaczego ta struktura danych nie jest używana dla rzeczywistych łańcuchów PHP? Czy nie doprowadziłoby to do zmniejszenia alokacji pamięci i lepszej wydajności?Dlaczego PHP nie używa wewnętrznego inteligentnego ciągu znaków?

+0

Ile bajtów mówimy? lol –

+0

@ AdamBuchananSmith Bytes czego? –

+0

Umm ... pamięci. –

Odpowiedz

6

Normalne łańcuchy PHP (od PHP 7) są reprezentowane przez typ zend_string, który zawiera zarówno długość łańcucha, jak i jego tablicę danych znakowych. zend_string s są zwykle przydzielane, aby dokładnie dopasować dane do znaków (niezależnie od wyrównania): nie zostawiają miejsca na dołączenie dodatkowych znaków.

Struktura smart_str zawiera wskaźnik do zend_string i wielkość alokacji. Tym razem, będzie , a nie precyzyjnie przydzielone. Zamiast tego alokacja zostanie za duża, aby dodatkowe znaki mogły być dołączone bez kosztownych realokacji.

Zasady realokacji dla smart_str jest następująca: Po pierwsze, zostanie przydzielone, aby mieć całkowity rozmiar 256 bajtów (minus nagłówek zend_string, minus narzut alokacji). Jeśli ten rozmiar zostanie przekroczony, zostanie ponownie przydzielony do 4096 bajtów (minus narzut). Następnie rozmiar zwiększy się z krokiem 4096 bajtów.

Teraz wyobraźmy sobie, że zamieniamy wszystkie łańcuchy na smart_str. Oznaczałoby to, że nawet pojedynczy ciąg znaków miałby minimalny rozmiar alokacji 256 bajtów. Biorąc pod uwagę, że większość używanych ciągów znaków jest niewielka, jest to niedopuszczalne obciążenie.

Zasadniczo jest to klasyczny kompromis między wydajnością a pamięcią. Korzystamy domyślnie z kompaktowej reprezentacji pamięci i przełączamy się na szybszą, ale mniej wydajną pod względem pamięci reprezentację w przypadkach, które najbardziej na tym skorzystają, tj. Przypadki, w których duże ciągi są konstruowane z małych części.

+0

Oczywiście, ale nadal można dostroić 'smart_str', aby lepiej dopasować się do normalnej obsługi ciągów PHP, prawda? Rozpoczynając od małego rozmiaru, a następnie podwajając go za każdym razem, gdy dochodzi do konkatenacji. Zwłaszcza, że ​​bufory ciągów są niemożliwe do wdrożenia w PHP (!). A także, zwłaszcza, że ​​pamięć jest obfitsza niż cykle procesora. –

+1

@ OlleHärstedt Tak, możliwe jest znalezienie rozsądnej polityki przydziałów po rozpoczęciu przechowywania pojemności w ogóle. Odpowiadałem tutaj konkretnie na temat smart_str. Jednym względnie bezpiecznym rozwiązaniem jest integracja z alokatorem i (dla małych alokacji) wybór następnego największego rozmiaru wiadra, które i tak będzie używane. Przy odrobinie sztuczek byłoby nawet możliwe wprowadzenie dodatkowego narzutu pamięci do przechowywania pojemności (przy użyciu kodowania pseudo-float). To właśnie robi HHVM;) – NikiC

+0

Hm, czy masz link do wyjaśnienia tej sztuczki? Brzmi interesująco. –

Powiązane problemy