Optimización de Diff
Optimización de diff
Esta guía muestra cómo limpiar un diff sin procesar — una lista de DiffOperation valores (ver Diff para cómo se construyen) — en una forma canónica y mínima usando los pases de post-procesamiento en el DiffOptimization sub-namespace. Cada pase implementa IDiffOptimizationOperation y muta la lista de diff in situ, de modo que los pases pueden encadenarse en secuencia para simplificar progresivamente el resultado.
El contrato de optimización
IDiffOptimizationOperation define un único método, Execute(diffs), que normaliza una lista mutable de valores DiffOperation in situ mientras preserva los textos origen y destino que representa el diff. Cada optimizador en este sub-espacio de nombres implementa esta interfaz, de modo que pueden invocarse de forma intercambiable o combinarse en una canalización.
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);Combinando operaciones adyacentes
OperationsMerger fusiona un diff en su forma canónica mínima: agrupa secuencias contiguas del mismo tipo de operación, y para una secuencia mixta de eliminación/inserción extrae cualquier prefijo común hacia la igualdad precedente y cualquier sufijo común hacia la igualdad siguiente.
var merger = new OperationsMerger(EditOperationsOrder.DeleteFirst);
merger.Execute(diffs);Eliminando igualdades cortas
MergingOptimizer realiza una pasada de limpieza semántica: elimina las igualdades que no son más extensas que las ediciones que las rodean, plegando esas breves secuencias comunes de nuevo en la operación de borrado/inserción contigua, y luego vuelve a combinar el resultado en forma canónica.
var semanticOptimizer = new MergingOptimizer(EditOperationsOrder.InsertFirst);
semanticOptimizer.Execute(diffs);Deslizamiento de ediciones sobre igualdades
OperationsSlideMerger desplaza lateralmente una única edición que está rodeada por igualdades en ambos lados, eliminando una de esas igualdades y canonizando aún más la diferencia.
IDiffOptimizationOperation slideMerger = new OperationsSlideMerger();
slideMerger.Execute(diffs);Control del orden de borrado/inserción
Cuando se emiten una eliminación y una inserción para la misma posición, el enumerado EditOperationsOrder determina cuál de ellas el optimizador coloca primero en la secuencia de operaciones resultante: DeleteFirst o InsertFirst.
var order = EditOperationsOrder.DeleteFirst;
var optimizer = new MergingOptimizer(order);
optimizer.Execute(diffs);Consejos y buenas prácticas
- Ejecute
OperationsMergerprimero para fusionar las ediciones sin procesar antes de aplicar las pasadas semánticas —MergingOptimizeryOperationsSlideMergerasumen que las operaciones contiguas del mismo tipo ya se han combinado. - Elija un único valor de
EditOperationsOrdery utilícelo de forma coherente en todos los optimizadores de la canalización; mezclarDeleteFirstyInsertFirstentre pasadas puede revertir el orden establecido por una pasada anterior. - Los tres optimizadores modifican el
List<DiffOperation>in situ — clona la lista primero si necesitas conservar el diff sin optimizar para compararlo. - Dado que cada optimizador implementa
IDiffOptimizationOperation, puedes mantener una canalización comoIDiffOptimizationOperation[]y ejecutarExecutesobre cada uno en un bucle en lugar de codificar manualmente cada paso por su nombre. - Aplica
OperationsSlideMergerdespués de las pasadas de fusión — desplazar una edición solo es útil una vez que las secuencias contiguas del mismo tipo ya se han fusionado.
Problemas comunes
| Problema | Causa | Solución |
|---|---|---|
| El diff aún contiene pequeñas igualdades fragmentadas | Solo se ejecutó OperationsMerger; las igualdades cortas entre ediciones nunca se plegaron | Ejecute también MergingOptimizer después de OperationsMerger |
| El orden de eliminación/inserción se invierte inesperadamente entre pasadas | Se pasaron valores diferentes de EditOperationsOrder a distintos optimizadores | Utilice el mismo valor de EditOperationsOrder para cada optimizador en la canalización |
| Parece que el optimizador no tiene efecto | La lista de diff ya estaba en forma canónica, o se optimizó una copia de la lista en lugar de la referencia original | Confirma que estás pasando la misma referencia List<DiffOperation> que el código downstream lee |
FAQ
¿Qué significa “forma canónica” para un diff?
Significa que las operaciones contiguas de la misma naturaleza se han fusionado y cualquier prefijo/sufijo común en secuencias mixtas de borrado/inserción se ha incorporado a la igualdad vecina, de modo que la secuencia no presenta fragmentación redundante.
¿Tengo que usar los tres optimizadores?
No. IDiffOptimizationOperation le permite aplicar solo las pasadas que necesita, pero ejecutar OperationsMerger antes de las pasadas semánticas (MergingOptimizer, OperationsSlideMerger) produce los resultados más consistentes.
¿Cuál es la diferencia entre OperationsMerger y MergingOptimizer?
OperationsMerger realiza una coalescencia estructural (secuencias de la misma clase, prefijo/sufijo común). MergingOptimizer va más allá y pliega igualdades breves rodeadas de ediciones de vuelta en el borrado o inserción adyacente antes de volver a fusionar.
¿EditOperationsOrder cambia lo que representa el diff?
No. Sólo controla el orden de emisión de un borrado y una inserción que se aplican a la misma posición — la reconstrucción del texto resultante no se ve afectada.
API Reference Resumen
| Clase / Método | Descripción |
|---|---|
IDiffOptimizationOperation | Interfaz para una pasada de post-procesamiento que normaliza un diff en el lugar |
IDiffOptimizationOperation.Execute(diffs) | Ejecuta la pasada de optimización sobre una lista mutable de valores DiffOperation |
OperationsMerger | Fusiona operaciones contiguas del mismo tipo y convierte prefijos/sufijos comunes en igualdades |
MergingOptimizer | Elimina igualdades cortas rodeadas por ediciones y luego vuelve a fusionarse en forma canónica |
OperationsSlideMerger | Desplaza una edición rodeada de igualdades para eliminar una de ellas |
EditOperationsOrder | Enum que controla si se emite DeleteFirst o InsertFirst en una posición compartida |