Po wprowadzeniu definicji funkcji, wprowadzasz je w określonej kolejności. W przypadku, gdy twoje definicje nie zawierają wzorów, są one przechowywane wewnętrznie w tabeli mieszającej. Gdy ich zażądasz, zostaną one domyślnie posortowane:
In[11]:=
Clear[g];
g[5]=1;
g[4]=2;
g[3]=3;
In[15]:= DownValues[g]
Out[15]= {HoldPattern[g[3]]:>3,HoldPattern[g[4]]:>2,HoldPattern[g[5]]:>1}
Jednak często możesz chcieć zobaczyć oryginalną kolejność, w której zostały przypisane wartości. Oto jak:
In[16]:= DownValues[g,Sort->False]
Out[16]= {HoldPattern[g[5]]:>1,HoldPattern[g[4]]:>2,HoldPattern[g[3]]:>3}
Przykładem jednej instancji, gdzie może chcesz go używać, to kiedy trzeba zaimplementować cache (moja próba zrobienia, że na podstawie tej opcji można znaleźć here). Jednak w przypadku dużej liczby definicji prawdopodobnie nie ma pewności, że definicje zostaną zastosowane w pierwotnej kolejności, ponieważ wewnętrzne tablice skrótów będą prawdopodobnie rozbudowywane i ponownie uruchamiane kilka razy. Zasadniczo implementacja tabeli mieszania nie gwarantuje kolejności, w której są przechowywane pary klucz-wartość. Więc, co osiągniesz ustawiając Sort->False
, to, że ...Values
nie są posortowane przez Mathematica, zanim zostaną ci zwrócone, więc otrzymujesz je w kolejności, w jakiej Mathematica aktualnie je przechowuje.
Innym przypadkiem, gdy może chcesz, jest to, kiedy chcesz zbudować strukturę podobną do słownika przy użyciu DownValues
- w tym przypadku ekstrakcja klucza będzie znacznie szybsza z Sort->False
, ponieważ nie trzeba sortować na zestawie kluczy (ma znaczenie dla dużych zestawów kluczy):
In[31]:=
Clear[gg];
(gg[#]:=200000-#)&/@Range[200000];
In[33]:= DownValues[gg][[All,1,1,1]]//Short//Timing
Out[33]= {4.867,{1,2,3,<<199994>>,199998,199999,200000}}
In[34]:= DownValues[gg,Sort->False][[All,1,1,1]]//Short//Timing
Out[34]= {2.103,{95090,102286,<<199996>>,38082,26686}}
Można znaleźć przykład takiego zastosowania, np. here.
O ile mi wiadomo, opcja Sort
wpływa tylko nie w oparciu o wzorce DownValues
(i inne ...Values
), bo w oparciu o wzorce DownValues
Mathematica w każdym razie próbuje uporządkować je w kolejności ich ogólności, jak to rozumie że. OTOH, w przypadku wzorcowania DownValues
, możesz wykonać ręczne ponowne zamawianie reguł, a Mathematica zachowa zmiany, natomiast w przypadku definicji bez wzorów próby ręcznej zmiany definicji po tym, jak zostały pierwotnie podane, nie mają na nie wpływu (być może, ponieważ są mieszane wewnętrznie, a tabele mieszające nie generalnie dbają o porządek).
czy możesz rozwinąć nieco na "... ponieważ wewnętrzne tablice mieszające zostaną prawdopodobnie rozszerzone i ponownie uruchomione kilka razy"? – acl
@ acl Typowy tablica hash ma określoną pojemność - wiele elementów może efektywnie mieszać, a prawdopodobieństwo kolizji nie jest zbyt wysokie. Gdy dodamy definicje, w pewnym momencie tablica haszowania prawdopodobnie wykona dynamiczną zmianę rozmiaru, zwiększając jej pojemność. Może, ale nie musi, ponownie haszować istniejące wpisy, w zależności od implementacji. Te rzeczy są bardzo ładnie wyjaśnione tutaj: http://en.wikipedia.org/wiki/Hash_table. Większość tabel mieszania nie obsługuje kolejności kluczy, ale istnieją pewne (np. 'LinkedHashMap' w Javie), które mają. –
dzięki. Sądzę, że bardziej pytałem, czy zaobserwowałeś to robiąc MMA, a jeśli tak, to jak. – acl