Frage

Ich bin derzeit die funktionale Programmierung in meiner Freizeit mit Scala, und ich habe eine Leerlauf-Neuling Frage zu lernen.

kann ich die Eleganz, die unveränderliche Objekte sehen, wenn, wie etwas zu tun Wavelet ein Haar Berechnung Transformation - d. H, wenn die Daten selbst durch die Objekte dargestellt werden, ändert sich nicht

Aber ich sah einen Blog, in dem jemand ein kleines Spiel als Beispiel hatte, als Unveränderlichkeit demonstriert. Wenn eine Kreatur Objekt Schaden empfangen, es hat seinen Zustand nicht ändern - es wieder eine neue Kreatur Objekt mit den neuen Hitpoints und einem neuen „aggro in Richtung X“ Flagge. Aber wenn wir so etwas wie ein MMORPG zu entwerfen waren, World of Warcraft sagen. Hundert Spieler in einem Schlachtfeld ... möglicherweise Tausende von Angriffen und Schwabbel / Abschwäch Zaubereffekte sie auf unterschiedliche Weise beeinflussen. Ist es noch möglich, das System mit völlig unveränderlichen Objekten zu entwerfen? Mir scheint es, als gäbe es eine ginormous Schwarm von neuen Instanzen jeder ‚tick‘ sein würde. Und die aktuell gültige Instanz von Objekten zu erhalten, würden alle Kunden müssen ständig durch eine Art zentraler „Spielwelt“ Objekt gehen, oder?

Ist die funktionale Programmierung Maßstab dafür, oder ist dies ein Fall von „bestem Werkzeug für die beste Arbeit, die wahrscheinlich nicht unveränderlich hier“?

War es hilfreich?

Lösung

  

Für mich es scheint, als gäbe es ein ginormous Schwarm von neuen Instanzen würde jeder ‚tick‘.

Tatsächlich ist das der Fall. Ich habe eine Haskell-Anwendung, die einen Marktdatenfeed liest (etwa fünf Millionen Nachrichten über den Verlauf eines sechsstündigen Handelstag, für die Daten, in denen wir interessiert sind) und unterhält „aktuellen Zustand“ für verschiedene Dinge, wie zum Beispiel der Letztes Gebot und Angebotspreise und Mengen für die Instrumente, wie gut unser Modell paßt auf den Markt, etc. etc. es ist ziemlich erschreckend einen Lauf dieses Programms gegen eine aufgezeichnete Feed in Profilierungsmodus zu simulieren und beobachten sie es zuweisen und GC Nähe von 288 TB Speicher (oder in der Nähe zu 50.000-fache der Größe meiner Maschine RAM) in den ersten 500 Sekunden seines Laufes. (Die Zahl würde ohne Profilierung deutlich höher sein, da Profilierung nicht nur verlangsamt die Anwendung, sondern auch zwingt sie alle auf einem Kern zu laufen, wie auch.)

Aber bedenken Sie, wird der Garbage Collector in reinen Sprachimplementierungen für diese Art von Verhalten optimiert. Ich bin ganz mit der Gesamtgeschwindigkeit meiner Anwendung glücklich, und ich denke, dass es ziemlich anspruchsvoll ist, dass wir mehr hundert Nachrichten pro Sekunde aus dem Markt-Feed zu analysieren haben, haben einige recht umfangreiche Berechnungen unser Modell zu bauen, und verwendet, die Modell Aufträge zu generieren, so schnell wie möglich auf den Austausch zu gehen.

Andere Tipps

Normalerweise in der funktionalen Programmierung werden Sie nicht C ++ Stil Konstrukteure haben. Dann, obwohl konzeptionell die ganze Zeit Sie Objekte erstellen, es bedeutet nicht, dass der Compiler Code zu machen hat ein neues Objekt zuweisen, weil es nicht das Verhalten des Programms beeinflussen kann. Da die Daten unveränderlich ist, kann der Compiler sehen, was gerade angegebenen Werte, die Sie haben, und das, was in Ihre Funktionen übergeben wurde.

Dann wird der Compiler können erstellen wirklich eng Code kompiliert, die die Felder in den spezifischen Objekte berechnet nur, wenn sie gebraucht werden. Wie gut das funktioniert, hängt von der Qualität des Compilers Sie verwenden. Allerdings sauber funktionale Programmierung Code teilt der Compiler eine ganze Menge mehr über Ihren Code als ein C-Compiler für ein ähnliches Programm könnte annehmen, und so also ein guter Compiler kann erzeugt besseren Code als das, was man erwarten könnte.

Also, zumindest in der Theorie, gibt es keinen Grund, besorgt zu sein; Programmierweise Implementierungen kann genauso gut skalieren als objektorientierte heap Implementierungen zuzuweisen. In der Praxis müssen Sie die Qualität der Sprachimplementierung verstehen, mit dem Sie arbeiten.

Ein MMORPG ist bereits ein Beispiel für Unveränderlichkeit. Da das Spiel auf verschiedene Server und Gamer Systeme verteilt ist, gibt es absolut keine zentrale ‚Spielwelt‘ Objekt. Somit kann jedes Objekt, das über die Leitung geschickt wird unveränderlich ist - weil es nicht durch den Empfänger geändert bekommt. Stattdessen wird ein neues Objekt oder eine Nachricht als Antwort gesendet wird, wenn es einen gibt.

Ich habe noch nie ein verteiltes Spiel geschrieben, damit ich weiß nicht genau, wie sie implementiert sind, aber ich vermute, dass Updates auf Objekte entweder berechnet lokal oder als diffs über den Draht gesendet.

Zum Beispiel sind Sie Command & Conquer zu spielen. Ihr Mammut Tank sitzt im Bereitschaftsmodus Ihre Basis bewacht. Dein Gegner nähert sich mit einem leichten Panzer Ihre Basis zu erkunden. Ihr Mammut-Panzer schießt und trifft gegnerische Panzer, was zu Schäden.

Dieses Spiel ist ziemlich einfach, so vermute ich, eine Menge berechnet wird lokal wann immer möglich. Angenommen, die beiden Spieler der Computer zunächst synchron in Bezug auf Spielzustand sind. Dann wird Ihr Gegner klickt sein Licht Tank in Ihrer Basis zu bewegen. Eine Meldung (unveränderlich) werden Sie über den Draht geschickt. Da der Algorithmus einen Tank zu bewegen ist (wahrscheinlich) deterministisch, Ihre Kopie von Command & Conquer kann gegnerische Panzer auf dem Bildschirm, die Aktualisierung Ihren Spielzustandes (könnte unveränderlich oder veränderlich sein) bewegen. Wenn das Licht Tank kommt in Reichweite des Mammut-Tank, den Tank Feuer. Ein Zufallswert auf dem Server erzeugt wird (in diesem Fall wird ein Computer willkürlich als Server gewählt wird), um zu bestimmen, ob der Schuss dein Gegner trifft oder nicht. Unter der Annahme, wurde der Tank getroffen und ein Update zum Tank des Gegners muss gemacht werden, nur der Unterschied - die Tatsache, dass die neue Rüstungsstufe Tank wird auf 22% verringert - über den Draht geschickt, um die zwei Spieler Spiele zu synchronisieren. Diese Meldung ist unveränderlich.

Ob das Objekt auf einem der Computer des Spielers den Tank darstellt Wandelbare oder unveränderlich ist irrelevant; es kann so oder so umgesetzt werden. Jeder Spieler nicht direkt den Zustand des Spiels anderer Spieler ändern.

Ein Punkt auf Unveränderlichkeit zu beachten ist, dass (wenn es richtig implementiert) es Objekterstellung relativ leicht macht. Wenn ein Feld unveränderlich ist, dann kann es zwischen den Instanzen gemeinsam genutzt werden.

Es ist wichtig zu berücksichtigen, wenn ein funktionsfähiges Programm entwerfen, die, wie Sie sagen, wird Unveränderliche Objekte gewissen Overhead haben. Es ist auch wichtig zu erinnern, dass von Objekten in der MMORPG-Programm mit unveränderlich seien es besser skalierbar von Natur aus sein wird. So kann die anfängliche Investition in Ausrüstung höher sein, aber auf der Straße wie die Dinge erweitern Sie in der Lage sein, Ihre Spieler-Basis zu skalieren.

Ein weiterer wichtiger Punkt ist, dass gerade jetzt eine die beefiest Maschinen haben 6 Kerne pro CPU. Betrachten wir ein Dual-CPU-Maschine mit 6 Adern jeweils. Einer dieser 12 Kerne können Garbage Collection tun und so den Aufwand von vielen Objekten Abbauen kann durch die Anwendung auf die anderen 11 Kerne leicht skalierbar ist ausgeglichen werden.

Denken Sie auch daran, dass nicht jedes Objekt (und es ist sub-Objekte) müssen vollständig auf einer Kopie wieder aufgebaut werden. Jeder Referenztyp, der nicht nur eine einzige Referenzzuordnung nehmen ändern, wenn ein Objekt „kopiert“.

Denken Sie nicht an Objekterstellung an der Drahtebene. Zum Beispiel wird wahrscheinlich eine optimierte Laufzeit für eine funktionale Sprache der Lage sein „zu betrügen“, wenn es um Ersatz eines Objekts kommt und tatsächlich tun Mutation der bestehenden Struktur, wenn es nichts weiß vollständig die ursprüngliche und die neue ersetzt wird verweisen. Denken Sie an Endrekursion Optimierung, aber angelegten Zustand zu widersprechen.

fand ich heute ein Blog, dass Angebote GENAU mit den Fragen, die ich in diesem Beitrag nicht angesprochen:

http://prog21.dadgum.com/23.html

Wie so ziemlich jedes Werkzeug in der Programmierung, sind Unveränderliche Objekte mächtig, aber gefährlich in der falschen Situation. Ich denke, das Spiel Beispiel nicht sehr gut ist oder zumindest sehr gekünstelt.

Eric Lippert hat einige interessante Beiträge zum Thema von Unveränderlichkeit, und sie sind ganz eine interessante Lektüre.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top