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 OperationsMerger primero para fusionar las ediciones sin procesar antes de aplicar las pasadas semánticas — MergingOptimizer y OperationsSlideMerger asumen que las operaciones contiguas del mismo tipo ya se han combinado.
  • Elija un único valor de EditOperationsOrder y utilícelo de forma coherente en todos los optimizadores de la canalización; mezclar DeleteFirst y InsertFirst entre 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 como IDiffOptimizationOperation[] y ejecutar Execute sobre cada uno en un bucle en lugar de codificar manualmente cada paso por su nombre.
  • Aplica OperationsSlideMerger despué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

ProblemaCausaSolución
El diff aún contiene pequeñas igualdades fragmentadasSolo se ejecutó OperationsMerger; las igualdades cortas entre ediciones nunca se plegaronEjecute también MergingOptimizer después de OperationsMerger
El orden de eliminación/inserción se invierte inesperadamente entre pasadasSe pasaron valores diferentes de EditOperationsOrder a distintos optimizadoresUtilice el mismo valor de EditOperationsOrder para cada optimizador en la canalización
Parece que el optimizador no tiene efectoLa lista de diff ya estaba en forma canónica, o se optimizó una copia de la lista en lugar de la referencia originalConfirma 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étodoDescripción
IDiffOptimizationOperationInterfaz 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
OperationsMergerFusiona operaciones contiguas del mismo tipo y convierte prefijos/sufijos comunes en igualdades
MergingOptimizerElimina igualdades cortas rodeadas por ediciones y luego vuelve a fusionarse en forma canónica
OperationsSlideMergerDesplaza una edición rodeada de igualdades para eliminar una de ellas
EditOperationsOrderEnum que controla si se emite DeleteFirst o InsertFirst en una posición compartida

Ver también

 Español