Jeder Text, den ich über Ruby-Symbole gelesen habe, spricht über die Effizienz von Symbolen über Strings. Aber das ist nicht die 70er Jahre. Mein Computer kann ein wenig zusätzliche Garbage Collection verarbeiten. Liege ich falsch? Ich habe den neuesten und besten Pentium Dual Core Prozessor und 4 GB RAM. Ich denke, das sollte genug sein, um ein paar Strings zu bewältigen.Sind moderne Computer nicht leistungsfähig genug, um Strings zu handhaben, ohne Symbole zu brauchen (in Ruby)
Antwort
Ihr Computer „ein wenig zusätzliche Garbage Collection“ zu handhaben kann gut sein können, aber was ist, wenn das „wenig“ findet in einer inneren Schleife, die läuft millionenfach? Was ist, wenn es auf einem eingebetteten System mit begrenztem Speicher ausgeführt wird?
Es gibt viele Orte, an denen Sie mit Strings Willy-Nilly, aber in einigen können Sie nicht wegkommen. Alles hängt vom Kontext ab.
Es ist schön, dass Symbole garantiert einzigartig sind - das kann einige nette Effekte haben, die Sie von String nicht bekommen würden (wie ihre Adressen immer genau gleich sind, glaube ich).
Plus sie haben eine andere Bedeutung und Sie würden sie in verschiedenen Bereichen verwenden möchten, aber Ruby ist sowieso nicht so streng über diese Art von Sachen, so kann ich Ihre Frage verstehen.
Es ist wahr, Sie brauchen Tokens nicht so sehr aus Speichergründen. Ihr Computer könnte zweifellos alle Arten von gnarly Schnurhandling behandeln.
Aber, zusätzlich zu sein, haben Token den zusätzlichen Vorteil (vor allem mit Kontext Färbung) von schreien visuell: Schau mich an, ich bin ein Schlüssel zu einem Schlüssel-Wert-Paar. Das ist ein guter Grund, sie für mich zu benutzen.
Es gibt noch andere Gründe ... und der Leistungszuwachs bei vielen von ihnen könnte mehr sein, als Ihnen bewusst ist, vor allem, wenn Sie etwas Vergleichendes machen.
Beim Vergleichen zweier Ruby-Symbole vergleicht der Interpreter nur zwei Objektadressen. Beim Vergleich zweier Strings muss der Interpreter jedes Zeichen einzeln vergleichen. Diese Art von Berechnung kann sich addieren, wenn Sie viel tun.
Symbole haben ihre eigenen Leistungsprobleme obwohl ... sie werden nie Müll gesammelt.
Es lohnt sich diesen Artikel lesen: http://www.randomhacks.net/articles/2007/01/20/13-ways-of-looking-at-a-ruby-symbol
Interessant. Ich habe nicht daran gedacht, dass Symbole nicht Müll sind. Cooler Artikel. Danke für den Link. Das ist wie "Alles, was du jemals über Symbole wissen wolltest" :) Friede, Alter. –
Die Kontext Färbung Sache ist auch ein guter Punkt. –
Ein Zeichen weniger eingeben. Das ist die ganze Rechtfertigung, die ich brauche, um sie über Zeichenfolgen für Hash-Schlüssel usw. zu verwenden.
+1; Als ich das zuerst las, sagte ich mir: "Wow, was für ein oberflächlicher Grund!". Aber je mehr ich darüber nachdachte, desto mehr wurde mir klar, wie groß diese Motivation für meinen eigenen Gebrauch von Symbolen war. Danke, dass du mir geholfen hast, etwas über mich selbst zu erkennen. –
Hier ist der wahre Grund für den Unterschied: Strings sind nie gleich. Jede Instanz einer Zeichenfolge ist ein separates Objekt, auch wenn der Inhalt identisch ist. Und die meisten Operationen an Strings machen neue String-Objekte. Beachten Sie Folgendes:
a = 'zowie'
b = 'zowie'
a == b #=> true
Auf der Oberfläche, würde es leicht sein, zu behaupten, dass a
und b
gleich sind. Die meisten gesunden Menschenverstand Operationen werden funktionieren, wie Sie es erwarten würden. Aber:
a.object_id #=> 2152589920 (when I ran this in irb)
b.object_id #=> 2152572980
a.equal?(b) #=> false
Sie aussehen die gleiche, aber sie sind verschiedene Objekte. Ruby musste Speicher zweimal reservieren, die Methode String#initialize
zweimal ausführen usw. Sie nehmen zwei getrennte Speicherplätze ein. Und hey!Es wird noch mehr Spaß, wenn Sie versuchen, sie zu ändern:
a += '' #=> 'zowie'
a.object_id #=> 2151845240
Hier fügen wir nichts-a
und lassen Sie den Inhalt genau das gleiche - aber Rubin weiß nicht, dass. Er weist immer noch ein ganz neues String-Objekt zu, weist ihm die Variable a
zu, und das alte String-Objekt wartet darauf, dass eine Garbage Collection stattfindet. Oh, und die leere ''
Zeichenfolge erhält auch ein temporäres String-Objekt, das nur für die Dauer dieser Codezeile zugewiesen wird. Probieren Sie es aus und sehen:
''.object_id #=> 2152710260
''.object_id #=> 2152694840
''.object_id #=> 2152681980
Sind diese Objektzuordnungen schnell auf glatten Multi-Gigahertz-Prozessor? Sicher sind sie. Werden sie viel von Ihrem 4 GB RAM kauen? Nein, werden sie nicht. Aber mach es ein paar Millionen Mal und es beginnt sich zu summieren. Die meisten Anwendungen verwenden überall temporäre Zeichenfolgen, und Ihr Code ist wahrscheinlich voll von Zeichenfolgenliteralen in Ihren Methoden und Schleifen. Jedes dieser Zeichenfolgenliterale und dergleichen weist ein neues Zeichenfolgenobjekt jedes Mal zu, in dem diese Codezeile ausgeführt wird. Das eigentliche Problem ist nicht einmal die Speicherverschwendung; Es ist die Zeit, die verschwendet wird, wenn die Garbage Collection zu häufig ausgelöst wird und die Anwendung zu hängen beginnt.
Im Gegensatz dazu einen Blick auf Symbole:
a = :zowie
b = :zowie
a.object_id #=> 456488
b.object_id #=> 456488
a == b #=> true
a.equal?(b) #=> true
Sobald das Symbol :zowie
gemacht wird, wird es nie wieder eine machen. Jedes Mal, wenn Sie auf ein bestimmtes Symbol verweisen, beziehen Sie sich auf dasselbe Objekt. Es gibt keine Zeit oder Speicher für neue Zuweisungen verschwendet. Dies kann auch ein Nachteil sein, wenn Sie zu verrückt mit ihnen gehen - sie sind nie Müll gesammelt, also wenn Sie beginnen, unzählige Symbole dynamisch von Benutzereingabe erstellen, riskieren Sie ein endloses Speicherleck. Aber für einfache Literale in Ihrem Code, wie konstante Werte oder Hash-Keys, sind sie einfach perfekt.
Hilft das? Es geht nicht darum, was Ihre Anwendung einmal tut. Es geht darum, was es millionenfach macht.
- 1. Wie handhaben moderne VMs die Speicherzuweisung?
- 2. Warum verwenden nicht mehr Projekte Ruby-Symbole anstelle von Strings?
- 3. R Swave Computer Moderne Schriftartenverwendung
- 4. worker_connections sind nicht genug
- 5. Ruby-Symbole sind kein Müll !? Dann ist es nicht besser, einen String zu verwenden?
- 6. PyQt: Wie Ereignis ohne Vererbung zu handhaben
- 7. Trim Dateiname, um kurz genug zu sein
- 8. Ist es genug, um XSS zu vermeiden?
- 9. nicht genug, um unterschiedliche Prognosen Bereich zu berechnen unter roc
- 10. Dropdown-Menü nicht lange genug geöffnet, um zu klicken
- 11. KDB +/Q Abfrage zu schwer zu handhaben
- 12. Swig: Der beste Weg, um eine vereinfachte Schnittstelle zu handhaben
- 13. brauchen Hilfe, um Facebook-Anwendung zu erstellen?
- 14. Haben mobile Geräte genug CPU, um HTTPS für den gesamten Datenverkehr einer Website zu unterstützen?
- 15. brauchen regulären Ausdruck, um Klammern zu entfernen
- 16. Warum sind Symbole nicht zentriert?
- 17. Wie man Symbole in Ruby versteht
- 18. Ruby-Implementierung is_numeric? für Strings, brauchen bessere Alternativen
- 19. Ereignis-Listener zu handhaben headtrackr.js
- 20. Nginx Fehler: Worker_connections sind nicht genug
- 21. generische Art und Weise Zahlen zu handhaben, ohne explizite Konvertierung
- 22. Wie leistungsfähig ist StackFrame?
- 23. Python: wie Zeitstempel zu handhaben (ISO8601)
- 24. Die moderne Art, Floating Content zu löschen?
- 25. NSMutableDictionary ist nicht lang genug zu halten
- 26. WebRTC Firefox: Nicht genug Argumente zu RTCPeerConnection.setLocalDescription
- 27. Python: Was sind effiziente Techniken, um tief verschachtelte Daten flexibel zu handhaben?
- 28. Wann sind Kommentare "zu viel" und wann sind sie nicht genug?
- 29. Wie zu handhaben riesige Daten in Java
- 30. visjs Symbole sind nicht in Chrom
Ja, das stimmt - eine lange laufende Schleife könnte definitiv Ressourcen verschlingen. Ich habe nicht darüber nachgedacht, Strings innerhalb einer Schleife zu erstellen, aber ich denke, Sie könnten das tun. Danke für den Tipp. –