Diff optimalizálás
Diff optimalizálás
Ez az útmutató bemutatja, hogyan lehet megtisztítani egy nyers diffet — egy listát a DiffOperation értékeket (lásd Diff arról, hogyan épülnek fel) — egy kanonikus, minimális formába a poszt-feldolgozó lépések használatával a DiffOptimization alkönyvtárban. Minden lépés megvalósítja IDiffOptimizationOperation és módosítja a diff listát helyben, így a lépések sorozatban láncolhatók, hogy fokozatosan egyszerűsítsék az eredményt.
Az optimalizálási szerződés
IDiffOptimizationOperation egyetlen metódust definiál, a Execute(diffs)-t, amely helyben normalizál egy módosítható DiffOperation értékek listáját, miközben megőrzi a diff által képviselt forrás- és cél szövegeket. A sub-névtér minden optimalizálója ezt az interfészt valósítja meg, így felcserélhetően hívhatóak vagy összefűzhetők egy csővezetékben.
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);Szomszédos műveletek összevonása
OperationsMerger egy diff-et a kanonikus minimális formájába egyesíti: összevonja az azonos művelettípusú szomszédos szekvenciákat, és egy vegyes delete/insert szekvenciánál a közös előtagot az előző egyenlőségbe, a közös utótagot a következő egyenlőségbe helyezi.
var merger = new OperationsMerger(EditOperationsOrder.DeleteFirst);
merger.Execute(diffs);Rövid egyenlőségek eltávolítása
MergingOptimizer egy szemantikus takarítási lépést hajt végre: eltávolítja azokat az egyenlőségeket, amelyek nem nagyobbak a körülöttük lévő szerkesztéseknél, visszahajtja ezeket a rövid közös sorozatokat a szomszédos delete/insert műveletbe, majd újra összeolvasztja az eredményt kanonikus formába.
var semanticOptimizer = new MergingOptimizer(EditOperationsOrder.InsertFirst);
semanticOptimizer.Execute(diffs);Szerkesztések csúsztatása egyenlőségek felett
OperationsSlideMerger egyetlen szerkesztést, amely mindkét oldalon egyenlőségek körül veszi körül, oldalirányban eltol, eltávolítva az egyenlőségek egyikét, és tovább kanonikalizálja a diff-et.
IDiffOptimizationOperation slideMerger = new OperationsSlideMerger();
slideMerger.Execute(diffs);A delete/insert sorrend szabályozása
Amikor egy delete és egy insert ugyanarra a pozícióra kerül kiadásra, a EditOperationsOrder felsorolt típus (enum) határozza meg, melyiket helyezi előre egy optimalizáló a keletkező műveletsorban: DeleteFirst vagy InsertFirst.
var order = EditOperationsOrder.DeleteFirst;
var optimizer = new MergingOptimizer(order);
optimizer.Execute(diffs);Tippek és bevált gyakorlatok
- Futtassa először a
OperationsMerger-t, hogy egyesítse a nyers szerkesztéseket a szemantikus lépések alkalmazása előtt — aMergingOptimizerés aOperationsSlideMergeregyaránt azt feltételezi, hogy a szomszédos azonos típusú műveletek már össze lettek kombinálva. - Válasszon egy
EditOperationsOrderértéket, és használja következetesen az összes optimalizálóban a csővezetékben; aDeleteFirstésInsertFirstkeverése a lépések között visszafordíthatja egy korábbi lépés által kialakított sorrendet. - Mindhárom optimalizáló a
List<DiffOperation>-t helyben módosítja — ha meg kell tartanod a nem optimalizált diffet az összehasonlításhoz, klónozd a listát előbb. - Mivel minden optimalizáló implementálja a
IDiffOptimizationOperation-t, a csővezetéket tárolhatodIDiffOptimizationOperation[]-ként, és egy ciklusban meghívhatod aExecute-t minden egyesnél, ahelyett, hogy nevek szerint kódolnád be minden lépést. - Alkalmazd a
OperationsSlideMerger-t a merge áthaladások után — egy szerkesztés csúsztatása csak akkor hasznos, ha a szomszédos azonos típusú futások már össze lettek olvasztva.
Gyakori problémák
| Probléma | Ok | Javítás |
|---|---|---|
| A diff még mindig apró, fragmentált egyenlőségeket tartalmaz | Csak a OperationsMerger lett futtatva; a szerkesztések közötti rövid egyenlőségek sosem lettek összecsukva | Futtasd a MergingOptimizer is a OperationsMerger után |
| A törlés/beszúrás sorrendje váratlanul megfordul a futások között | Különböző EditOperationsOrder értékek lettek átadva különböző optimalizálóknak | Használd ugyanazt a EditOperationsOrder értéket a csővezeték minden optimalizálójához |
| Úgy tűnik, hogy az optimalizáló nem jár hatással | A diff lista már kanonikus formában volt, vagy a lista egy másolata lett optimalizálva az eredeti hivatkozás helyett | Erősítsd meg, hogy ugyanazt a List<DiffOperation> hivatkozást adod át, amelyet a downstream kód olvas |
FAQ
Mit jelent a “kanonikus forma” egy diff esetén?
Ez azt jelenti, hogy az azonos típusú szomszédos műveletek össze lettek olvasztva, és a vegyes törlés/beszúrás futásokban előforduló közös elő- vagy utótag be lett olvasztva a szomszédos egyenlőségbe, így a sorozat nem tartalmaz felesleges fragmentációt.
Kell-e mindhárom optimalizálót használnom?
Nem. A IDiffOptimizationOperation lehetővé teszi, hogy csak a szükséges áthaladásokat alkalmazd, de a OperationsMerger futtatása a szemantikai áthaladások (MergingOptimizer, OperationsSlideMerger) előtt a legkonzisztensebb eredményeket adja.
Mi a különbség a OperationsMerger és a MergingOptimizer között?
OperationsMerger structural coalescing-et hajt végre (azonos típusú futamok, közös előtag/utótag). MergingOptimizer tovább megy, és a szerkesztések által körülvett rövid egyenlőségeket visszafordítja a szomszédos delete/insert-be az újraösszefésülés előtt.
Megváltoztatja a EditOperationsOrder a diff által ábrázolt tartalmat?
Nem. Csak a delete és az insert kibocsátási sorrendjét szabályozza, amelyek ugyanarra a pozícióra vonatkoznak — a végeredményül kapott szöveg rekonstrukciója nem változik.
API Reference összefoglaló
| Osztály / Metódus | Leírás |
|---|---|
IDiffOptimizationOperation | Interfész egy post-processing lépéshez, amely helyben normalizálja a diffet |
IDiffOptimizationOperation.Execute(diffs) | Futtatja az optimalizációs lépést egy módosítható DiffOperation értékek listáján |
OperationsMerger | Összevonja a szomszédos azonos típusú műveleteket, és a közös előtagot/utótagot egyenlőségekbe faktorizálja |
MergingOptimizer | Eltávolítja a rövid egyenlőségeket, amelyek szerkesztések által körül vannak véve, majd újra egyesíti őket kanonikus formába |
OperationsSlideMerger | Eltol egy szerkesztést, amely egyenlőségek közé van ágyazva, hogy egyiküket megszüntesse |
EditOperationsOrder | Enum, amely szabályozza, hogy DeleteFirst vagy InsertFirst kerül kiadásra egy közös pozíción |