To znaczy, jeśli użyję bieżącego czasu jako indeksu do tablicy:
array[Date.getTime()] = value;
czy interpreter utworzy instancję wszystkich elementów od 0 do teraz? Czy różne przeglądarki robią to inaczej?
Pamiętam, że kiedyś był błąd w jądrze AIX , który tworzył pseudo-ttys na żądanie, ale gdybyś zrobił, powiedzmy, "echo> / dev / pty10000000000", utworzyłby / dev / pty0, / dev / pty1, .... a potem padnij martwy. Było fajnie na targach, ale nie chcę, żeby przytrafiło się to moim klientom.
javascript
sparse-matrix
Jagoda
źródło
źródło
Odpowiedzi:
Sposób implementacji tablic JavaScript różni się w zależności od przeglądarki, ale generalnie sprowadzają się do rzadkiej implementacji - najprawdopodobniej tej samej, która jest używana do dostępu do właściwości zwykłych obiektów - jeśli użycie rzeczywistej tablicy byłoby nieefektywne.
Będziesz musiał poprosić kogoś, kto ma większą wiedzę na temat konkretnych implementacji, aby odpowiedział, co dokładnie wyzwala przejście z gęstej na rzadką, ale twój przykład powinien być całkowicie bezpieczny. Jeśli chcesz uzyskać gęstą tablicę, powinieneś wywołać konstruktor z jawnym argumentem długości i mieć nadzieję, że faktycznie go otrzymasz.
Zobacz tę odpowiedź, aby uzyskać bardziej szczegółowy opis autorstwa olliej.
źródło
foo = new Array(10000)
. Jednak to ma pracę:foo = Array.apply(null, {length: 10});
.Tak, oni są. W rzeczywistości są wewnętrznie tablicami mieszającymi, więc możesz używać nie tylko dużych liczb całkowitych, ale także łańcuchów, liczb zmiennoprzecinkowych i innych obiektów. Wszystkie klucze są konwertowane na ciągi znaków przez
toString()
przed dodaniem do skrótu. Możesz to potwierdzić za pomocą kodu testowego:Wyświetlacze:
Zwróć uwagę, jak użyłem
for...in
składni, która podaje tylko te indeksy, które są faktycznie zdefiniowane. Jeśli używasz bardziej powszechnegofor (var i = 0; i < array.length; ++i)
stylu iteracji, będziesz oczywiście miał problemy z niestandardowymi indeksami tablicowymi.źródło
length
właściwościąlength
jest niewidoczny tylko wfor..in
pętlach, ponieważ maDontEnum
ustawioną flagę; w ES5 atrybut property jest wywoływanyenumerable
i można go jawnie ustawić za pośrednictwemObject.defineProperty()
String
; wszystko inne, co umieścisz w indeksie dolnym, zostanietoString()
-ed. Połącz to z nieprecyzyjną liczbą całkowitą dużej liczby i oznacza to, że jeśli ustawisza[9999999999999999]=1
,a[10000000000000000]
będzie 1 (i wiele innych zaskakujących zachowań). Używanie liczb niecałkowitych jako kluczy jest bardzo nierozsądne, a dowolne obiekty są natychmiastowe.Możesz uniknąć tego problemu, używając składni javascript zaprojektowanej do tego typu rzeczy. Możesz traktować go jak słownik, ale składnia „for ... in…” pozwoli ci je wszystkie pobrać.
źródło
Obiekty JavaScript są rzadkie, a tablice to tylko wyspecjalizowane obiekty z automatycznie utrzymywaną właściwością length (która jest w rzeczywistości o jeden większa niż największy indeks, a nie liczba zdefiniowanych elementów) i kilkoma dodatkowymi metodami. Tak czy inaczej jesteś bezpieczny; użyj tablicy, jeśli potrzebujesz jej dodatkowych funkcji, lub obiektu w przeciwnym razie.
źródło
Odpowiedź, jak zwykle w przypadku JavaScript, brzmi „to trochę dziwniejsze ...”
Użycie pamięci nie jest zdefiniowane i każda implementacja może być głupia. Teoretycznie
const a = []; a[1000000]=0;
mógłby spalić megabajty pamięci, tak jak mógłbyconst a = [];
. W praktyce nawet Microsoft unika tych implementacji.Justin Love zwraca uwagę, że atrybut długości jest najwyższy zestaw indeksów. ALE jest aktualizowany tylko wtedy, gdy indeks jest liczbą całkowitą.
Tak więc tablica jest rzadka. ALE wbudowane funkcje, takie jak redukuj (), Math.max () i „for ... of”, przechodzą przez cały zakres możliwych indeksów całkowitych od 0 do długości, odwiedzając wiele zwracających „undefined”. ALE pętle 'for ... in' mogą działać zgodnie z oczekiwaniami, odwiedzając tylko zdefiniowane klucze.
Oto przykład wykorzystujący Node.js:
dający:
Ale. Jest więcej przypadków narożnych z tablicami, o których jeszcze nie wspomniano.
źródło
Rzadkość (lub gęstość) można potwierdzić empirycznie dla NodeJS za pomocą niestandardowego procesu. PamięćUsage () .
Czasami węzeł jest na tyle sprytny, że tablica jest rzadka:
Czasami node decyduje się na zagęszczenie (to zachowanie może być zoptymalizowane w przyszłości):
Następnie ponownie rzadkie:
Być może więc użycie gęstej tablicy, aby wyczuć błąd oryginalnego jądra AIX, może wymagać wymuszenia podobnego zakresu :
Bo dlaczego nie sprawić, by się przewróciło?
źródło
Mogą, ale nie zawsze muszą, i mogą osiągać lepsze wyniki, gdy nie są.
Oto dyskusja na temat testowania rzadkości indeksów w instancji tablicy: https://benmccormick.org/2018/06/19/code-golf-sparse-arrays/
Zwycięzcą tego kodu golfa (najmniej znaków) jest:
Zasadniczo chodzenie po tablicy indeksowanych wpisów przy jednoczesnym zmniejszaniu wartości długości i zwracaniu wzmocnionej wartości
!!
logicznej fałszywego / prawdziwego wyniku liczbowego (jeśli akumulator jest zmniejszony do zera, indeks jest w pełni zapełniony i nie jest rzadki). Należy również wziąć pod uwagę powyższe zastrzeżenia Charlesa Merriama, a ten kod ich nie rozwiązuje, ale odnoszą się do haszowanych wpisów łańcuchowych, co może się zdarzyć podczas przypisywania elementów, warr[var]= (something)
których zmienna nie była liczbą całkowitą.Powodem, dla którego warto przejmować się rzadkością indeksów, jest jego wpływ na wydajność, który może różnić się w zależności od silnika skryptowego. Tutaj znajduje się obszerna dyskusja na temat tworzenia / inicjalizacji tablic: Jaka jest różnica między „Array ()” a „[]” podczas deklarowania kodu JavaScript szyk?
Niedawna odpowiedź na ten post zawiera link do tego dogłębnego zagłębienia się w to, jak V8 próbuje zoptymalizować tablice, oznaczając je, aby uniknąć (ponownego) testowania pod kątem cech takich jak rzadkość: https://v8.dev/blog/elements-kinds . Wpis na blogu pochodzi z września 2017 r., A materiał może ulec pewnym zmianom, ale zestawienie implikacji dla codziennego rozwoju jest przydatne i jasne.
źródło