Βελτιστοποίηση Diff
Βελτιστοποίηση Diff
Αυτός ο οδηγός δείχνει πώς να καθαρίσετε ένα ακατέργαστο diff — μια λίστα από DiffOperation τιμές (δείτε Diff για το πώς αυτά δημιουργούνται) — σε μια κανονική, ελάχιστη μορφή χρησιμοποιώντας τα στάδια επεξεργασίας μετά από το DiffOptimization sub-namespace. Κάθε στάδιο υλοποιεί IDiffOptimizationOperation και τροποποιεί τη λίστα diff επί τόπου, ώστε τα στάδια να μπορούν να συνδυαστούν διαδοχικά για να απλοποιούν προοδευτικά το αποτέλεσμα.
Η σύμβαση βελτιστοποίησης
IDiffOptimizationOperation ορίζει μια ενιαία μέθοδο, Execute(diffs), η οποία κανονικοποιεί μια μεταβλητή λίστα τιμών DiffOperation επί τόπου, διατηρώντας τα κείμενα προέλευσης και προορισμού που αντιπροσωπεύει το diff. Κάθε βελτιστοποιητής σε αυτόν τον υπο-χώρο ονομάτων υλοποιεί αυτό το interface, ώστε να μπορούν να κληθούν εναλλάξ ή να συντεθούν σε μια αλυσίδα.
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);Συγχώνευση γειτονικών λειτουργιών
OperationsMerger συγχωνεύει ένα diff στη κανονική ελάχιστη μορφή του: συνενώνει διαδοχικές ακολουθίες του ίδιου τύπου λειτουργίας, και για μια μικτή ακολουθία διαγραφής/εισαγωγής εξάγει τυχόν κοινό πρόθεμα στην προηγούμενη ισότητα και τυχόν κοινό επίθημα στην επόμενη ισότητα.
var merger = new OperationsMerger(EditOperationsOrder.DeleteFirst);
merger.Execute(diffs);Απαλοιφή σύντομων ισοτήτων
MergingOptimizer εκτελεί μια σημασιολογική φάση καθαρισμού: αφαιρεί τις ισότητες που δεν είναι μεγαλύτερες από τις επεμβάσεις που τις περιβάλλουν, ενσωματώνοντας αυτές τις σύντομες κοινές ακολουθίες πίσω στην παρακείμενη διαγραφή/εισαγωγή, και στη συνέχεια επανασυγχωνεύει το αποτέλεσμα σε κανονική μορφή.
var semanticOptimizer = new MergingOptimizer(EditOperationsOrder.InsertFirst);
semanticOptimizer.Execute(diffs);Μετακίνηση επεμβάσεων δια μέσου ισοτήτων
OperationsSlideMerger μετατοπίζει μια μοναδική επεμβαση που περιβάλλεται και από τις δύο πλευρές με ισότητες, αφαιρώντας μία από αυτές τις ισότητες και περαιτέρω κανονικοποιώντας τη διαφορά.
IDiffOptimizationOperation slideMerger = new OperationsSlideMerger();
slideMerger.Execute(diffs);Έλεγχος σειράς διαγραφής/εισαγωγής
Όταν μια διαγραφή και μια εισαγωγή εκδίδονται για την ίδια θέση, η αρίθμηση EditOperationsOrder ελέγχει ποια από τις δύο το βελτιστοποιητής τοποθετεί πρώτα στη σειρά των τελικών λειτουργιών: DeleteFirst ή InsertFirst.
var order = EditOperationsOrder.DeleteFirst;
var optimizer = new MergingOptimizer(order);
optimizer.Execute(diffs);Συμβουλές και βέλτιστες πρακτικές
- Εκτελέστε το
OperationsMergerπρώτα για να ενοποιήσετε τις ακατέργαστες επεμβάσεις πριν εφαρμόσετε τις σημασιολογικές φάσεις — ταMergingOptimizerκαιOperationsSlideMergerυποθέτουν και τα δύο ότι οι παρακείμενες λειτουργίες του ίδιου τύπου έχουν ήδη συνδυαστεί. - Επιλέξτε μια τιμή
EditOperationsOrderκαι χρησιμοποιήστε την σταθερά σε κάθε βελτιστοποιητή μιας αλυσίδας επεξεργασίας· η ανάμειξη τωνDeleteFirstκαιInsertFirstμεταξύ των φάσεων μπορεί να αναιρέσει τη σειρά που καθόρισε μια προηγούμενη φάση. - Οι τρεις βελτιστοποιητές τροποποιούν το
List<DiffOperation>επί τόπου — αντιγράψτε τη λίστα πρώτα αν χρειάζεται να διατηρήσετε το μη βελτιστοποιημένο diff για σύγκριση. - Επειδή κάθε βελτιστοποιητής υλοποιεί το
IDiffOptimizationOperation, μπορείτε να διατηρήσετε μια αλυσίδα ωςIDiffOptimizationOperation[]και να καλέσετε τοExecuteσε κάθε στοιχείο σε βρόχο αντί να κωδικοποιείτε σκληρά κάθε πέρασμα με όνομα. - Εφαρμόστε το
OperationsSlideMergerμετά τα βήματα συγχώνευσης — η μετακίνηση μιας επεξεργασίας είναι χρήσιμη μόνο όταν οι διαδοχικές ακολουθίες του ίδιου τύπου έχουν ήδη συγχωνευτεί.
Συνηθισμένα Προβλήματα
| Πρόβλημα | Αιτία | Διόρθωση |
|---|---|---|
| Diff εξακολουθεί να περιέχει μικρές κατακερματισμένες ισότητες | Μόνο το OperationsMerger εκτελέστηκε· οι σύντομες ισότητες μεταξύ των επεξεργασιών δεν συμπτύχθηκαν ποτέ | Εκτελέστε επίσης το MergingOptimizer μετά το OperationsMerger |
| Η σειρά διαγραφής/εισαγωγής αλλάζει απροσδόκητα μεταξύ των περασμάτων | Διαφορετικές τιμές EditOperationsOrder περάστηκαν σε διαφορετικούς βελτιστοποιητές | Χρησιμοποιήστε την ίδια τιμή EditOperationsOrder για κάθε βελτιστοποιητή στο pipeline |
| Ο βελτιστοποιητής φαίνεται να μην έχει καμία επίδραση | Η λίστα diff ήταν ήδη σε κανονική μορφή, ή ένα αντίγραφο της λίστας βελτιστοποιήθηκε αντί της αρχικής αναφοράς | Επιβεβαιώστε ότι περνάτε την ίδια αναφορά List<DiffOperation> που διαβάζει ο κώδικας downstream |
FAQ
Τι σημαίνει «καναονική μορφή» για ένα diff;
Σημαίνει ότι οι διαδοχικές λειτουργίες του ίδιου τύπου έχουν συγχωνευτεί και οποιοδήποτε κοινό πρόθεμα/επίθεμα σε μιγμένα τμήματα διαγραφής/εισαγωγής έχει ενσωματωθεί στην παρεμφερή ισότητα, έτσι ώστε η ακολουθία να μην έχει περιττό κατακερματισμό.
Πρέπει να χρησιμοποιήσω και τους τρεις βελτιστοποιητές;
Όχι. IDiffOptimizationOperation σας επιτρέπει να εφαρμόζετε μόνο τις διεργασίες που χρειάζεστε, αλλά η εκτέλεση του OperationsMerger πριν από τις σημασιολογικές διεργασίες (MergingOptimizer, OperationsSlideMerger) δίνει τα πιο συνεπή αποτελέσματα.
Ποια είναι η διαφορά μεταξύ OperationsMerger και MergingOptimizer;
OperationsMerger εκτελεί δομική συγχώνευση (ακολουθίες ίδους τύπου, κοινό πρόθεμα/επίθημα). MergingOptimizer προχωρά περαιτέρω και ενσωματώνει σύντομες ισότητες που περιβάλλονται από επεξεργασίες πίσω στην παρακείμενη διαγραφή/εισαγωγή πριν από την επανασυγχώνευση.
Αλλάζει το EditOperationsOrder το τι αντιπροσωπεύει το diff;
Όχι. Ελέγχει μόνο τη σειρά εκπομπής μιας διαγραφής και μιας εισαγωγής που εφαρμόζονται στην ίδια θέση — η τελική ανακατασκευή του κειμένου δεν επηρεάζεται.
API Reference Σύνοψη
| Κλάση / Μέθοδος | Περιγραφή |
|---|---|
IDiffOptimizationOperation | Διεπαφή για μια φάση μεταεπεξεργασίας που κανονικοποιεί ένα diff επί τόπου |
IDiffOptimizationOperation.Execute(diffs) | Εκτελεί τη φάση βελτιστοποίησης πάνω σε μια μεταβλητή λίστα τιμών DiffOperation |
OperationsMerger | Συγχωνεύει διαδοχικές λειτουργίες του ίδιου είδους και εξάγει τα κοινά πρόθεμα/επίθημα σε ισότητες |
MergingOptimizer | Καταργεί σύντομες ισότητες που περιβάλλονται από επεμβάσεις, και στη συνέχεια τις ενώνει ξανά σε κανονική μορφή |
OperationsSlideMerger | Μετακινεί μια επεμβαση που περιβάλλεται από ισότητες ώστε να εξαλείψει μία από αυτές |
EditOperationsOrder | Απαρίθμηση που ελέγχει αν θα εκδοθεί το DeleteFirst ή το InsertFirst σε κοινή θέση |