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
OperationsMergerförst för att samla råa redigeringar innan de semantiska passen tillämpas —MergingOptimizerochOperationsSlideMergerfö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 blandaDeleteFirstochInsertFirstmellan 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
IDiffOptimizationOperationkan du hålla en pipeline somIDiffOptimizationOperation[]och anropaExecutepå varje i en loop snarare än att hårdkoda varje pass med namn. - Applicera
OperationsSlideMergerefter sammanslagningspassen — att glida en redigering är bara användbart när intilliggande sekvenser av samma typ redan har slagits ihop.
Vanliga problem
| Problem | Orsak | Fix |
|---|---|---|
| Diff innehåller fortfarande små fragmenterade likheter | Endast OperationsMerger kördes; korta likheter mellan redigeringar sammanfogades aldrig | Kör även MergingOptimizer efter OperationsMerger |
| Raderings-/infogningsordningen vänder oväntat mellan pass | Olika EditOperationsOrder-värden skickades till olika optimerare | Använd samma EditOperationsOrder-värde för varje optimerare i pipeline |
| Optimeraren verkar ha ingen effekt | Difflistan var redan i kanonisk form, eller så optimerades en kopia av listan istället för den ursprungliga referensen | Bekrä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 / Metod | Beskrivning |
|---|---|
IDiffOptimizationOperation | Grä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 |
OperationsMerger | Koaliserar intilliggande operationer av samma typ och faktorerar gemensamt prefix/suffix till likheter |
MergingOptimizer | Eliminerar korta likheter som omges av redigeringar och återfogar sedan till kanonisk form |
OperationsSlideMerger | Flyttar en redigering som omges av likheter för att eliminera en av dem |
EditOperationsOrder | Enum som styr om DeleteFirst eller InsertFirst skrivs ut på en gemensam position |