การเพิ่มประสิทธิภาพ Diff
การเพิ่มประสิทธิภาพ Diff
คู่มือนี้แสดงวิธีทำความสะอาด raw diff — รายการของ DiffOperation ค่า (ดู Diff สำหรับวิธีการสร้างของพวกมัน) — ให้เป็นรูปแบบมาตรฐานและขั้นต่ำโดยใช้ขั้นตอน post-processing ใน DiffOptimization sub-namespace. แต่ละขั้นตอนทำงานโดย IDiffOptimizationOperation และเปลี่ยนแปลงรายการ diff ตรงที่เดิม ทำให้ขั้นตอนต่าง ๆ สามารถต่อเชื่อมต่อกันเป็นลำดับเพื่อค่อย ๆ ทำให้ผลลัพธ์ง่ายลง.
สัญญาการเพิ่มประสิทธิภาพ
IDiffOptimizationOperation นิยามเมธอดเดียว, Execute(diffs), ที่ทำให้รายการ DiffOperation ที่แก้ไขได้เป็นมาตรฐานในที่เดิมขณะรักษาข้อความต้นทางและปลายทางที่ diff แสดง. ตัวเพิ่มประสิทธิภาพทุกตัวใน sub-namespace นี้ดำเนินการตามอินเทอร์เฟซนี้, ดังนั้นจึงสามารถเรียกใช้แทนกันได้หรือรวมเป็น 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);การรวมการดำเนินการที่อยู่ติดกัน
OperationsMerger รวม diff ให้เป็นรูปแบบมาตรฐานขนาดขั้นต่ำ: มันรวมลำดับที่ต่อเนื่องของประเภทการดำเนินการเดียวกัน, และสำหรับลำดับที่ผสม delete/insert จะย้ายส่วนพรีฟิกซ์ที่ซ้ำกันไปยัง equality ก่อนหน้าและส่วนซัฟฟิกซ์ที่ซ้ำกันไปยัง equality ถัดไป.
var merger = new OperationsMerger(EditOperationsOrder.DeleteFirst);
merger.Execute(diffs);การกำจัด equality สั้น
MergingOptimizer ทำการทำความสะอาดเชิงความหมาย: มันกำจัดความเท่าเทียมที่ไม่ใหญ่กว่าการแก้ไขที่ล้อมรอบ, พับชุดสั้นที่ทั่วไปเหล่านั้นกลับเข้าไปใน delete/insert ที่อยู่ใกล้เคียง, แล้วทำการรวมผลลัพธ์ใหม่ให้เป็น canonical form.
var semanticOptimizer = new MergingOptimizer(EditOperationsOrder.InsertFirst);
semanticOptimizer.Execute(diffs);การเลื่อนการแก้ไขข้ามความเท่าเทียม
OperationsSlideMerger เลื่อนการแก้ไขเดียวที่ถูกล้อมรอบด้วยความเท่าเทียมทั้งสองด้านไปด้านข้าง, กำจัดความเท่าเทียมหนึ่งรายการและทำให้ diff กลายเป็น canonical มากยิ่งขึ้น.
IDiffOptimizationOperation slideMerger = new OperationsSlideMerger();
slideMerger.Execute(diffs);การควบคุมลำดับ delete/insert
เมื่อมีการส่งออก delete และ insert สำหรับตำแหน่งเดียวกัน, enum EditOperationsOrder จะควบคุมว่าตัวใดที่ optimizer จะวางไว้ก่อนในลำดับการดำเนินการที่ได้: DeleteFirst หรือ InsertFirst.
var order = EditOperationsOrder.DeleteFirst;
var optimizer = new MergingOptimizer(order);
optimizer.Execute(diffs);เคล็ดลับและแนวทางปฏิบัติที่ดีที่สุด
- เรียกใช้
OperationsMergerก่อนเพื่อรวมการแก้ไขดิบก่อนที่จะทำการผ่านเชิงความหมาย —MergingOptimizerและOperationsSlideMergerสมมติว่าการดำเนินการประเภทเดียวกันที่อยู่ติดกันได้ถูกรวมแล้ว. - เลือกค่า
EditOperationsOrderหนึ่งค่าและใช้มันอย่างสม่ำเสมอในทุก optimizer ภายใน pipeline; การผสมDeleteFirstและInsertFirstระหว่างการผ่านอาจทำให้ลำดับที่ผ่านก่อนหน้านี้ตั้งไว้ถูกยกเลิก. - ออปติไมเซอร์ทั้งสามตัวจะทำการเปลี่ยนแปลง
List<DiffOperation>ที่ตำแหน่งเดิม — ให้คัดลอกรายการก่อนหากคุณต้องการเก็บ diff ที่ยังไม่ได้ออปติไมซ์เพื่อเปรียบเทียบ. - เนื่องจากออปติไมเซอร์ทุกตัวทำงานตาม
IDiffOptimizationOperationคุณสามารถเก็บ pipeline เป็นIDiffOptimizationOperation[]และเรียกExecuteบนแต่ละออปติไมเซอร์ในลูป แทนการกำหนดชื่อแต่ละขั้นตอนอย่างตายตัว. - ใช้
OperationsSlideMergerหลังจากขั้นตอนการรวม — การเลื่อนการแก้ไขมีประโยชน์เฉพาะเมื่อรันที่อยู่ติดกันของประเภทเดียวกันถูกรวมเข้าด้วยกันแล้ว.
ปัญหาทั่วไป
| ปัญหา | สาเหตุ | วิธีแก้ไข |
|---|---|---|
| Diff ยังมีความเท่าเทียมขนาดเล็กที่แยกเป็นส่วนย่อย | Only OperationsMerger was run; short equalities between edits were never folded | Also run MergingOptimizer after OperationsMerger |
| Delete/insert order flips unexpectedly between passes | Different EditOperationsOrder values were passed to different optimizers | Use the same EditOperationsOrder value for every optimizer in the pipeline |
| Optimizer appears to have no effect | The diff list was already in canonical form, or a copy of the list was optimized instead of the original reference | ยืนยันว่าคุณกำลังส่งอ้างอิง List<DiffOperation> เดียวกันที่โค้ด downstream อ่าน |
FAQ
“รูปแบบมาตรฐาน” หมายความว่าอย่างไรสำหรับ diff?
หมายความว่าการดำเนินการที่อยู่ติดกันของชนิดเดียวกันถูกรวมเข้าด้วยกันแล้ว และคำนำหน้า/ต่อท้ายที่ซ้ำกันในรันที่เป็นการลบ/แทรกผสมกันได้ถูกยุบเข้าไปในส่วนเท่ากันที่อยู่ใกล้เคียง ดังนั้นลำดับจะแไม่มีการแบ่งส่วนที่ซ้ำซ้อน.
ฉันจำเป็นต้องใช้ทุกออปติไมเซอร์ทั้งสามหรือไม่?
No. IDiffOptimizationOperation ให้คุณใช้เฉพาะขั้นตอนที่ต้องการเท่านั้น แต่การรัน OperationsMerger ก่อนขั้นตอนเชิงความหมาย (MergingOptimizer, OperationsSlideMerger) จะให้ผลลัพธ์ที่สอดคล้องที่สุด.
ความแตกต่างระหว่าง OperationsMerger กับ MergingOptimizer คืออะไร?
OperationsMerger ทำการรวมโครงสร้าง (การเรียงลำดับแบบเดียวกัน, คำนำหน้า/ต่อท้ายที่เหมือนกัน) MergingOptimizer ทำต่อไปและพับความเท่าเทียมสั้นที่อยู่ระหว่างการแก้ไขกลับเข้าไปใน delete/insert ที่อยู่ติดกันก่อนทำการรวมใหม่.
EditOperationsOrder เปลี่ยนสิ่งที่ diff แสดงหรือไม่?
No. มันเพียงควบคุมลำดับการส่งออกของการลบและการแทรกที่ใช้กับตำแหน่งเดียวกัน — การสร้างข้อความผลลัพธ์ไม่ได้รับผลกระทบ.
API Reference สรุป
| คลาส / เมธอด | คำอธิบาย |
|---|---|
IDiffOptimizationOperation | อินเทอร์เฟซสำหรับการผ่านการประมวลผลหลังที่ทำให้ diff เป็นมาตรฐานในที่เดียว |
IDiffOptimizationOperation.Execute(diffs) | ทำการรันขั้นตอนการเพิ่มประสิทธิภาพบนรายการที่แก้ไขได้ของค่า DiffOperation |
OperationsMerger | รวมการดำเนินการชนิดเดียวกันที่อยู่ติดกันและแยกส่วนพรีฟิกซ์/ซัฟฟิกซ์ที่เหมือนกันเป็นสมการที่เท่าเทียมกัน |
MergingOptimizer | กำจัดสมการสั้นที่อยู่ระหว่างการแก้ไข แล้วผสานใหม่เป็นรูปแบบมาตรฐาน |
OperationsSlideMerger | ย้ายการแก้ไขที่อยู่ระหว่างสมการเพื่อกำจัดหนึ่งในนั้น |
EditOperationsOrder | Enum ที่ควบคุมว่าจะส่งออก DeleteFirst หรือ InsertFirst ที่ตำแหน่งร่วม |