אופטימיזציית Diff

אופטימיזציית Diff

אופטימיזציית Diff

מדריך זה מציג כיצד לנקות diff גולמי — רשימה של DiffOperation ערכים (ראה Diff כיצד הם נבנים) — לצורה קנונית, מינימלית באמצעות מעברי העיבוד שלאחר מכן ב- DiffOptimization תת-מרחב השם. כל מעבר מיישם IDiffOptimizationOperation ומשנה את רשימת ה-diff במקום, כך שהמעברים יכולים להיות מקושרים ברצף כדי לפשט את התוצאה באופן הדרגתי.


חוזה האופטימיזציה

IDiffOptimizationOperation מגדיר שיטה יחידה, Execute(diffs), שמנרמלת רשימה ניתנת לשינוי של ערכי DiffOperation במקום תוך שמירה על טקסטי המקור והיעד שה-diff מייצג. כל אופטימייזר בתת-מרחב השמות הזה מממש את הממשק הזה, ולכן ניתן לקרוא להם באופן החלף או להרכיב אותם בצינור.

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> במקום — שכפל את הרשימה תחילה אם אתה צריך לשמור על ההבדל הבלתי-אופטימלי לצורך השוואה.
  • מאחר שכל אופטימייזר מממש את IDiffOptimizationOperation, אתה יכול להחזיק צינור עבודה כ-IDiffOptimizationOperation[] ולקרוא ל-Execute על כל אחד בלולאה במקום לקודד במפורש כל שלב בשם.
  • החל את OperationsSlideMerger אחרי שלבי המיזוג — החלקת עריכה שימושית רק לאחר שרצפים סמוכים מאותו סוג כבר מוזגים.

בעיות נפוצות

בעיהגורםתיקון
ה-Diff עדיין מכיל שוויונים קטנים מקוטעיםרק OperationsMerger הורץ; שוויונים קצרים בין העריכות מעולם לא קופלוהפעל גם את MergingOptimizer אחרי OperationsMerger
סדר המחיקה/ההוספה מתהפך באופן בלתי צפוי בין ריצותערכי EditOperationsOrder שונים נשלחו לאופטימייזרים שוניםהשתמש באותו ערך של EditOperationsOrder עבור כל אופטימייזר בצינור
נראה שהאופטימייזר אינו משפיערשימת ה-diff הייתה כבר בצורה קנונית, או שהעתק של הרשימה באופטימיזציה במקום ההפנייה המקוריתאשר שאתה מעביר את אותה הפנייה List<DiffOperation> שהקוד התחתון קורא

FAQ

מה משמעות “צורה קנונית” עבור diff?

זה אומר שהפעולות הסמוכות מאותו סוג מוזגו וכי כל קידומת/סיומת משותפת בריצות משולבות של מחיקה/הוספה קופצה לתוך השוויון השכני, כך שהרצף אינו מכיל פיצול מיותר.

האם עליי להשתמש בכל שלושת האופטימייזרים?

לא. IDiffOptimizationOperation מאפשר לך להפעיל רק את ההעברות שאתה צריך, אך הרצת OperationsMerger לפני ההעברות הסמנטיות (MergingOptimizer, OperationsSlideMerger) נותנת את התוצאות העקביות ביותר.

מה ההבדל בין OperationsMerger ל-MergingOptimizer?

OperationsMerger מבצע קואלציית מבנה (רצפים מאותו סוג, קידומת/סיומת משותפת). MergingOptimizer הולך צעד נוסף וקורא שוויונים קצרים שמוקפים בעריכות חזרה לתוך המחיקה/ההוספה הסמוכה לפני מיזוג מחדש.

האם EditOperationsOrder משנה את מה שה-diff מייצג?

לא. הוא רק שולט בסדר ההפצה של מחיקה והוספה החלים על אותה מיקום — שיחזור הטקסט המתקבל אינו מושפע.


API Reference סיכום

מחלקה / מתודהתיאור
IDiffOptimizationOperationממשק עבור שלב עיבוד לאחרון שמנרמל diff במקום
IDiffOptimizationOperation.Execute(diffs)מריץ את שלב האופטימיזציה על רשימה ניתנת לשינוי של ערכי DiffOperation values
OperationsMergerמאחד פעולות סמוכות מאותו סוג ומפרק קידומת/סיומת משותפת לשוויונים
MergingOptimizerמבטל שוויונים קצרים המוקפים בעריכות, ואז ממזג מחדש לצורה קנונית
OperationsSlideMergerהזזת עריכה המוקפת בשוויונים כדי לבטל אחת מהן
EditOperationsOrderEnum ששולט האם DeleteFirst או InsertFirst נשלחים במיקום משותף

ראה גם

 עברית