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 — a MergingOptimizer és a OperationsSlideMerger egyará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; a DeleteFirst és InsertFirst keveré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árolhatod IDiffOptimizationOperation[]-ként, és egy ciklusban meghívhatod a Execute-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émaOkJavítás
A diff még mindig apró, fragmentált egyenlőségeket tartalmazCsak a OperationsMerger lett futtatva; a szerkesztések közötti rövid egyenlőségek sosem lettek összecsukvaFuttasd a MergingOptimizer is a OperationsMerger után
A törlés/beszúrás sorrendje váratlanul megfordul a futások közöttKülönböző EditOperationsOrder értékek lettek átadva különböző optimalizálóknakHaszná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ássalA diff lista már kanonikus formában volt, vagy a lista egy másolata lett optimalizálva az eredeti hivatkozás helyettErő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ódusLeírás
IDiffOptimizationOperationInterfé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
MergingOptimizerEltá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
OperationsSlideMergerEltol egy szerkesztést, amely egyenlőségek közé van ágyazva, hogy egyiküket megszüntesse
EditOperationsOrderEnum, amely szabályozza, hogy DeleteFirst vagy InsertFirst kerül kiadásra egy közös pozíción

Lásd még:

 Magyar