Copy-and-Patch es una técnica de optimización de bajo nivel que implica copiar una sección de código ejecutable (o datos) de su ubicación original a una nueva región de memoria, aplicar modificaciones (parches) a la copia, y luego ejecutar la versión parcheada. El objetivo principal es mejorar la localidad de caché, reducir la contención en el bus de memoria o permitir optimizaciones específicas del contexto que serían difíciles o imposibles de realizar en el código original in situ. A menudo se utiliza en escenarios donde el código es genérico pero puede beneficiarse de adaptaciones dinámicas para un caso de uso particular, evitando ramas condicionales costosas o accesos a memoria dispersos.

Esta técnica encuentra aplicación en varios sistemas de alto rendimiento. En el kernel de Linux, se utiliza para optimizar rutas de código críticas, como las que manejan interrupciones o llamadas al sistema, especialmente en arquitecturas x86 con 'alternatives' o 'jump labels'. Permite que el kernel reemplace instrucciones genéricas con versiones más rápidas y específicas de la CPU en tiempo de arranque o ejecución. Otro ejemplo es en compiladores Just-In-Time (JIT) como los de la Java Virtual Machine (JVM) o motores JavaScript (V8), donde el código bytecode se compila a código máquina nativo y se optimiza dinámicamente. En estos entornos, Copy-and-Patch puede usarse para especializar funciones para tipos de datos específicos o para eliminar comprobaciones de límites redundantes, generando versiones de código más eficientes que se ejecutan directamente en la CPU.

Para un arquitecto de sistemas, Copy-and-Patch es relevante por su impacto en el rendimiento y la complejidad. Ofrece la capacidad de lograr optimizaciones de micro-arquitectura significativas, reduciendo la latencia y aumentando el throughput en rutas de código críticas. Sin embargo, introduce complejidad en la gestión de la memoria y la coherencia del código. Se deben considerar cuidadosamente los trade-offs: el costo de copiar y parchear el código en tiempo de ejecución (que puede ser considerable para secciones grandes o frecuentes) frente a las ganancias de rendimiento obtenidas. También plantea desafíos en la depuración y la observabilidad, ya que el código ejecutado no es idéntico al código fuente original. Un arquitecto debe evaluar si las ganancias de rendimiento justifican la sobrecarga de diseño, la complejidad de implementación y el potencial aumento de la superficie de ataque si no se gestiona correctamente la seguridad de la memoria.