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?
Odpowiedz
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.
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. –
@ 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
Hm, czy masz link do wyjaśnienia tej sztuczki? Brzmi interesująco. –
- 1. Dlaczego firma maven używa mojego wewnętrznego repozytorium przed lokalnym repozytorium?
- 2. Dlaczego Perl nie obsługuje operatora normalnego [] do indeksowania ciągu znaków?
- 3. php: Usunąć konkretny indeks z ciągu znaków?
- 4. Uzyskaj właściwość klasy PHP według ciągu znaków
- 5. Wykonywanie kodu PHP w ciągu znaków
- 6. php: usunąć nawiasy/zawartość z ciągu znaków?
- 7. Funkcja PHP do zwracania ciągu znaków
- 8. Dlaczego mój plik PHP używa MAMP nie odświeżający?
- 9. Dlaczego nie można uchwycić wewnętrznego wyjątku?
- 10. String.Format nie formatuje ciągu znaków
- 11. Dlaczego decltype w ciągu znaków literowych nie daje typu tablicy?
- 12. Dlaczego regex nie dba o długość ciągu znaków
- 13. Dlaczego "ciąg znaków" jest uważany za uproszczoną wersję "ciągu znaków"?
- 14. Dlaczego IntelliJ nie używa kart?
- 15. Odpowiednik PHP znajomego lub wewnętrznego
- 16. Usuwanie znaków niealfanumerycznych z ciągu znaków
- 17. Usuwanie znaków z ciągu znaków
- 18. Dlaczego Java char używa UTF-16?
- 19. PHP: Eksplodować przy użyciu znaków specjalnych
- 20. Jaki jest limit rozmiaru zmiennej PHP podczas przechowywania ciągu znaków?
- 21. pytania dotyczące źródła ciągu znaków?
- 22. usunięcia nie angielskich znaków PHP
- 23. std :: ostringstream nie zwraca poprawnego ciągu znaków
- 24. Nie można przekonwertować ciągu znaków na int32
- 25. Nie można konwertować ciągu znaków na JsonArray
- 26. 500 Błąd wewnętrznego serwera?
- 27. Linq do zwracania ciągu znaków
- 28. Funkcja PHP strtoupper dla ciągu znaków UTF-8
- 29. Jak mogę uzyskać zrzut heksadecymalny ciągu znaków w PHP?
- 30. Pierwsze 10 znaków ciągu?
Ile bajtów mówimy? lol –
@ AdamBuchananSmith Bytes czego? –
Umm ... pamięci. –