Diff-optimering

Diffoptimering

Denna guide visar hur man rensar upp en rå diff — en lista med DiffOperation värden (se Diff för hur dessa byggs) — till ett kanoniskt, minimalt format med hjälp av efterbearbetningsstegen i DiffOptimization sub-namnutrymmet. Varje steg implementerar IDiffOptimizationOperation och muterar diff-listan på plats, så stegen kan kedjas i sekvens för att successivt förenkla resultatet.


Optimeringskontraktet

IDiffOptimizationOperation definierar en enda metod, Execute(diffs), som normaliserar en muterbar lista av DiffOperation-värden på plats samtidigt som den bevarar käll- och destinationstexterna som diffen representerar. Varje optimerare i detta undernamn implementerar detta gränssnitt, så de kan anropas omväxlande eller komponeras i en pipeline.

List<DiffOperation> diffs = new List<DiffOperation>
{
    new DiffOperation(Operation.Equal, "The quick "),
    new DiffOperation(Operation.Delete, "brown "),
    new DiffOperation(Operation.Insert, "red "),
    new DiffOperation(Operation.Equal, "fox")
};

IDiffOptimizationOperation optimizer = new OperationsMerger(EditOperationsOrder.DeleteFirst);
optimizer.Execute(diffs);

Sammanfoga intilliggande operationer

OperationsMerger slår ihop en diff till dess kanoniska minimala form: den koaliserar intilliggande sekvenser av samma operationstyp, och för en blandad delete/insert-sekvens faktorisera den eventuellt gemensamt prefix in i den föregående likheten och eventuellt gemensamt suffix in i den efterföljande likheten.

var merger = new OperationsMerger(EditOperationsOrder.DeleteFirst);
merger.Execute(diffs);

Eliminera korta likheter

MergingOptimizer utför ett semantiskt rensningssteg: det eliminerar likvärdigheter som inte är större än redigeringarna som omger dem, viker tillbaka de korta gemensamma sekvenserna in i den intilliggande delete/insert och slår sedan samman resultatet till kanonisk form.

var semanticOptimizer = new MergingOptimizer(EditOperationsOrder.InsertFirst);
semanticOptimizer.Execute(diffs);

Glidande redigeringar över likvärdigheter

OperationsSlideMerger förskjuter en enskild redigering som är omgiven på båda sidor av likvärdigheter åt sidan, eliminerar en av dessa likvärdigheter och kanoniserar diffen ytterligare.

IDiffOptimizationOperation slideMerger = new OperationsSlideMerger();
slideMerger.Execute(diffs);

Styrning av delete/insert-ordning

När en delete och en insert avges för samma position styr EditOperationsOrder enum vilken som en optimerare placerar först i den resulterande operationsekvensen: DeleteFirst eller InsertFirst.

var order = EditOperationsOrder.DeleteFirst;
var optimizer = new MergingOptimizer(order);
optimizer.Execute(diffs);

Tips och bästa praxis

  • Kör OperationsMerger först för att samla råa redigeringar innan de semantiska passen tillämpas — MergingOptimizer och OperationsSlideMerger förutsätter båda att intilliggande operationer av samma slag redan har kombinerats.
  • Välj ett EditOperationsOrder-värde och använd det konsekvent i alla optimerare i en pipeline; att blanda DeleteFirst och InsertFirst mellan passen kan upphäva den ordning som ett tidigare pass etablerade.
  • Alla tre optimerare modifierar List<DiffOperation> på plats — klona listan först om du behöver behålla den ooptimerade diffen för jämförelse.
  • Eftersom varje optimerare implementerar IDiffOptimizationOperation kan du hålla en pipeline som IDiffOptimizationOperation[] och anropa Execute på varje i en loop snarare än att hårdkoda varje pass med namn.
  • Applicera OperationsSlideMerger efter sammanslagningspassen — att glida en redigering är bara användbart när intilliggande sekvenser av samma typ redan har slagits ihop.

Vanliga problem

ProblemOrsakFix
Diff innehåller fortfarande små fragmenterade likheterEndast OperationsMerger kördes; korta likheter mellan redigeringar sammanfogades aldrigKör även MergingOptimizer efter OperationsMerger
Raderings-/infogningsordningen vänder oväntat mellan passOlika EditOperationsOrder-värden skickades till olika optimerareAnvänd samma EditOperationsOrder-värde för varje optimerare i pipeline
Optimeraren verkar ha ingen effektDifflistan var redan i kanonisk form, eller så optimerades en kopia av listan istället för den ursprungliga referensenBekräfta att du skickar samma List<DiffOperation>-referens som nedströmskod läser

FAQ

Vad betyder “canonical form” för en diff?

Det betyder att intilliggande operationer av samma typ har slagits ihop och eventuella gemensamma prefix/suffix i blandade delete/insert-sekvenser har lagts in i den närliggande equality, så sekvensen har ingen överflödig fragmentering.

Måste jag använda alla tre optimerare?

Nej. IDiffOptimizationOperation låter dig bara tillämpa de pass du behöver, men att köra OperationsMerger före de semantiska passen (MergingOptimizer, OperationsSlideMerger) ger de mest konsekventa resultaten.

Vad är skillnaden mellan OperationsMerger och MergingOptimizer?

OperationsMerger utför strukturell sammanslagning (samma typ av sekvenser, gemensamt prefix/suffix). MergingOptimizer går längre och viker in korta likheter som omges av redigeringar tillbaka i den intilliggande borttagningen/infogningen innan den återfogas.

Ändrar EditOperationsOrder vad diffen representerar?

Nej. Den styr bara utsändningsordningen för en borttagning och en infogning som gäller samma position — den resulterande textrekonstruktionen påverkas inte.


API Reference Sammanfattning

Klass / MetodBeskrivning
IDiffOptimizationOperationGränssnitt för ett efterbehandlingspass som normaliserar en diff på plats
IDiffOptimizationOperation.Execute(diffs)Kör optimeringspasset över en muterbar lista med DiffOperation-värden
OperationsMergerKoaliserar intilliggande operationer av samma typ och faktorerar gemensamt prefix/suffix till likheter
MergingOptimizerEliminerar korta likheter som omges av redigeringar och återfogar sedan till kanonisk form
OperationsSlideMergerFlyttar en redigering som omges av likheter för att eliminera en av dem
EditOperationsOrderEnum som styr om DeleteFirst eller InsertFirst skrivs ut på en gemensam position

Se även

 Svenska