Der Grund, warum ich Rcpp so sehr mag, ist, dass ich nicht immer verstehe, wie R Core denkt, und mit Rcpp muss ich das meistens nicht.
Jeder Wert philosophisch gesprochen, du ist in einem Zustand der Sünde in Bezug auf das funktionale Paradigma, das, um sicherzustellen versucht , erscheint unabhängig von jedem anderen Wert; Das Ändern eines Werts sollte niemals zu einer sichtbaren Änderung eines anderen Werts führen, wie dies bei Zeigern der Fall ist, die die Darstellung in C teilen.
Die Probleme entstehen, wenn die funktionale Programmierung dem kleinen Fahrzeug signalisiert, sich aus dem Weg zu räumen, und das kleine Fahrzeug antwortet: "Ich bin ein Leuchtturm". Wenn Sie eine lange Reihe kleiner Änderungen an einem großen Objekt vornehmen, das Sie in der Zwischenzeit bearbeiten möchten, befinden Sie sich auf dem Gebiet des Leuchtturms.
In der C ++ STL push_back()
ist eine Lebensweise. Es versucht nicht, funktionsfähig zu sein, aber es versucht, gängige Programmiersprachen effizient zu berücksichtigen .
Mit etwas Klugheit hinter den Kulissen kann man manchmal arrangieren, einen Fuß in jeder Welt zu haben. Snapshot-basierte Dateisysteme sind ein gutes Beispiel (das sich aus Konzepten wie Union Mounts entwickelt hat, die auch beide Seiten bedienen).
Wenn R Core dies tun wollte, könnte der zugrunde liegende Vektorspeicher wie ein Union Mount funktionieren. Ein Verweis auf den Vektorspeicher ist möglicherweise für Indizes gültig 1:N
, während ein anderer Verweis auf denselben Speicher für Indizes gültig ist 1:(N+1)
. Es könnte reservierten Speicher geben, auf den noch nichts anderes verweist, als es für einen schnellen Zweck geeignet ist push_back()
. Sie verstoßen nicht gegen das Funktionskonzept, wenn Sie außerhalb des Bereichs anhängen, den eine vorhandene Referenz für gültig hält.
Wenn Sie Zeilen schrittweise anhängen, geht Ihnen der reservierte Speicherplatz aus. Sie müssen von allem neue Kopien erstellen, wobei der Speicher mit einem gewissen Inkrement multipliziert wird. Die von mir verwendeten STL-Implementierungen multiplizieren den Speicher bei Erweiterung der Zuordnung in der Regel mit 2. Ich dachte, ich hätte in R Internals gelesen, dass es eine Speicherstruktur gibt, in der der Speicher um 20% erhöht wird. In beiden Fällen erfolgen Wachstumsoperationen mit logarithmischer Häufigkeit im Verhältnis zur Gesamtzahl der angehängten Elemente. Amortisiert ist dies normalerweise akzeptabel.
Als Tricks hinter den Kulissen gehen, habe ich Schlimmeres gesehen. Jedes Mal, wenn Sie push_back()
eine neue Zeile in den Datenrahmen einfügen, muss eine Indexstruktur der obersten Ebene kopiert werden. Die neue Zeile kann an eine gemeinsame Darstellung angehängt werden, ohne dass alte Funktionswerte beeinträchtigt werden. Ich glaube nicht einmal, dass dies den Müllsammler sehr erschweren würde. da ich nicht vorschlage, dass push_front()
alle Referenzen Präfixreferenzen auf der Vorderseite des zugewiesenen Vektorspeichers sind.
append()
[was wahrscheinlich als Einfügen bezeichnet werden sollte] verwenden oderc()
Elemente am Ende einer Liste hinzufügen, was Ihnen hier jedoch nicht weiterhilft.