accumulate

___ qstnhdr ___ Effiziente Akkumulation ___ answer39494205 ___

Die effiziente Verwendung von %code% ohne redundante Kopien ist nicht offensichtlich Zusätzlich dazu, dass der akkumulierende Wert neu zugewiesen und in und aus dem Lambda übergeben wird, kann er intern durch die Implementierung kopiert werden.
Beachten Sie außerdem, dass %code% selbst den Anfangswert by-value verwendet , einen copy-ctor aufrufen und somit% code% s ignorieren, das auf der Quelle der Kopie ausgeführt wurde (wie in einigen der anderen Antworten vorgeschlagen).

Der effizienteste Weg, die Strings zu verketten, ist folgender:

%Vor%

Das Ergebnis wird in %code% angezeigt.
Diese Implementierung enthält keine redundanten Kopien, Verschiebungen oder Neuzuordnungen.

    
___ answer19664335 ___

Versuchen Sie Folgendes

%Vor%

Vor diesem Aufruf ist es vielleicht sinnvoll,

anzurufen %Vor%     
___ answer19666300 ___

Dies ist ein bisschen schwierig, da zwei Operationen sind, der Zusatz und die Zuordnung. Um die Kopien zu vermeiden, Sie müssen die Zeichenfolge im Zusatz und ändern Stellen Sie sicher, dass die Zuweisung ein No-Op ist. Es ist der zweite Teil Das ist schwierig.

Was ich gelegentlich getan habe, ist einen benutzerdefinierten "Akkumulator" zu erstellen, in Anlehnung an:

%Vor%

Beim Aufruf von %code% und von Rückgabewert, aber während der tatsächlichen Akkumulation nichts. Gerade Aufrufen:

%Vor%

(Wenn Sie sich wirklich Gedanken über die Leistung machen, können Sie hinzufügen ein Kapazitätsargument für den Konstruktor von %code% , so dass es möglich ist Führen Sie %code% für die Member-Zeichenfolge aus. Wenn ich das täte, würde ich schreiben Sie wahrscheinlich auch den Kopierkonstruktor, um das sicherzustellen Die Zeichenfolge im kopierten Objekt hatte die erforderliche Kapazität.)

    
___ tag123c ___ C ++ ist eine universelle Programmiersprache. Es wurde ursprünglich als Erweiterung von C entworfen und behält eine ähnliche Syntax, ist aber jetzt eine komplett andere Sprache. Verwenden Sie dieses Tag für Fragen zu Code, der mit einem C ++ - Compiler kompiliert werden soll. ___ tag123c11 ___ C ++ 11 ist eine 2011 verabschiedete Version des C ++ - Sprachstandards. Sie hat viele Änderungen und Ergänzungen der Kernsprache sowie der verbesserten und erweiterten C ++ - Standardbibliothek vorgenommen. ___ answer19664362 ___

Ich würde dies in zwei Operationen aufteilen, zuerst %code% , um die Gesamtlänge der zu erstellenden Zeichenfolge zu erhalten, dann eine %code% mit einem Lambda, das die lokale Zeichenfolge aktualisiert:

%Vor%

Die gebräuchlichste Alternative ist die Verwendung von Ausdrucksvorlagen, die jedoch nicht in eine Antwort passen. Grundsätzlich erstellen Sie eine Datenstruktur, die die Operationen abbildet, aber nicht ausführt. Wenn der Ausdruck schließlich ausgewertet wird, kann er die Informationen, die er benötigt, im Voraus sammeln und verwenden, um den Platz zu reservieren und die Kopien zu erstellen. Der Code, der die Ausdrucksvorlage verwendet, ist schöner, aber komplizierter.

    
___ tag123rvaluereference ___ Eine rvalue-Referenz ist ein neues Sprachfeature in C ++ 11, das eine Referenz auf einen rvalue darstellt. Zusammen mit dem Referenz-Collapsing werden sie verwendet, um eine Bewegungssemantik und eine perfekte Weiterleitung zu implementieren und zu ermöglichen. ___ tag123algorithm ___ Ein Algorithmus ist eine Folge wohldefinierter Schritte, die eine abstrakte Lösung für ein Problem definieren. Verwenden Sie dieses Tag, wenn sich Ihr Problem auf den Algorithmusentwurf bezieht. ___ tag123akkumulieren ___ Die Akkumulation bezieht sich auf den Vorgang des wiederholten Kombinierens des zuvor berechneten Ergebnisses mit dem nächsten Artikel, bis der Vorrat an Artikeln erschöpft ist. ___ qstntxt ___

Angenommen, ich habe einen Vektor von Strings und möchte sie über std :: accumulate verketten.

Wenn ich den folgenden Code verwende:

%Vor%

Ich kann ziemlich sicher sein, dass es eine temporäre Objektkonstruktion geben wird.

In dieser Antwort wird gesagt, dass der Effekt von std :: accumulate folgendermaßen angegeben wird:

  

Berechnet das Ergebnis durch Initialisierung des Akkumulators acc mit   Initialwert init und ändert es dann mit acc = acc + * i oder acc =   binary_op (acc, * i) für jeden Iterator i im Bereich [first, last] in   bestellen.

Also frage ich mich, was ist der richtige Weg, dies zu tun, um die unnötige temporäre Objektkonstruktion zu vermeiden.

Eine Idee war, das Lambda so zu ändern:

%Vor%

In diesem Fall dachte ich, dass ich eine effiziente Verkettung der Strings erzwinge und dem Compiler helfe (ich weiß, dass ich ) die unnötige Kopie weglassen, da dies (Pseudocode) entsprechen sollte:

%Vor%

und somit

%Vor%

Eine andere Idee war es,

zu verwenden %Vor%

Aber das würde wahrscheinlich zu etwas wie:

führen %Vor%

Was mir sehr verdächtig erscheint.

Was ist der richtige Weg dies zu schreiben, um das Risiko der unnötigen Erstellung von temporären Objekten zu minimieren? Ich interessiere mich nicht nur für std :: string, ich wäre glücklich, eine Lösung zu haben, die wahrscheinlich für jedes Objekt funktionieren würde, das Kopier- und Verschiebungskonstruktoren / Zuordnungen implementiert hat.

    
___
2
Antworten

C ++ Vektor akkumuliert

Ich habe versucht, die Akkumulationsfunktion für Vektoren zu verwenden %Vor% aber ich habe immer B = 0, während A nicht-Null-Werte hatte     
22.11.2011, 13:29
4
Antworten

Effiziente Akkumulation

Angenommen, ich habe einen Vektor von Strings und möchte sie über std :: accumulate verketten. Wenn ich den folgenden Code verwende: %Vor% Ich kann ziemlich sicher sein, dass es eine temporäre Objektkonstruktion geben wird. In dieser...
29.10.2013, 16:40