2015-09-12 30 views
5

Próbuję przekonwertować program ruby ​​na kryształ.Język Crystal: co używać zamiast runtime String :: to_sym

i jestem skazany brakuje string.to_sym

Mam duży plik XML, który jest zbyt duży, aby zmieścić się w pamięci. A więc przeanalizowanie tego wszystkiego nie wchodzi w grę. Na szczęście nie potrzebuję wszystkich informacji, tylko ich część. Więc sam je parsuję, upuszczając większość linii. Kiedyś String::to_sym do przechowywania danych, takich jak to:

:param_name1 => 1 
:param_name2 => 11 
:param_name1 => 2 
:param_name2 => 22 
:param_name1 => 3 
:param_name2 => 33 

Co należy użyć w krysztale? Pamięć jest wąskim gardłem. Nie chcę wielokrotnie przechowywać param_name1.

Odpowiedz

6

Jeśli masz znaną listę parametrów można na przykład użyć ENUM:

enum Parameter 
    Name1 
    Name2 
    Name3 
end 

a = "Name1" 
b = {'N', 'a', 'm', 'e', '1'}.join 
pp a.object_id == b.object_id # => false 
pp Parameter.parse(a) == Parameter.parse(b) # => true 

Jeżeli lista parametrów jest nieznany można użyć mniej wydajny StringPool:

require "string_pool" 

pool = StringPool.new 

a = "param1" 
b = {'p', 'a', 'r', 'a', 'm', '1'}.join 

pp a.object_id == b.object_id # => false 
a = pool.get(a) 
b = pool.get(b) 
pp a.object_id == b.object_id # => true 
+0

jestem trochę zdezorientowany, więc przy kompilacji kryształ ma niezmienne łańcuchy i symbole, ale nie widzę różnicy między nimi. A także Enums. I tylko Enums są użyteczne w czasie wykonywania (pobieranie int32 z nazwy). And StringPool jest ekwiwalentem runtime dla Symbol? – jsaak

+0

Symbole są tłumaczone na unikalny numer podczas kompilacji, więc ich reprezentacja pamięci jest pojedynczym numerem. Dlatego nie można ich tworzyć dynamicznie, wartości są przypisywane niedeterministycznie w czasie kompilacji, a tabela nie może być rozszerzona w czasie wykonywania. –

+0

Ciągi są niezmienne, ale z pełnymi danymi w pamięci, dzięki czemu można wykonywać operacje na ich rzeczywistej wartości ciągu, symbole, które trzeba najpierw przekonwertować na wartość ciągu znaków. StringPool jest po prostu wygodnym API podczas wyszukiwania Hash/Set, który deduplikuje instancje. –