BookinglyTech News
Software

scc vs mezura: análisis de rendimiento y optimización con strace

El autor de scc comparó su herramienta con mezura, encontró una brecha de 2,56x y la achacó a un cuello de botella de un solo goroutine.

2 min de lecturaLobsters0 vistas

Un usuario abrió un issue en el repositorio de scc señalando a un rival, mezura, que afirma ser más rápido. El autor, lejos de molestarse, decidió comprobarlo con hyperfine sobre el árbol fuente de Linux. Los resultados: mezura completó el análisis en 200 ms frente a los 512 ms de scc, una diferencia de 2,56 veces a favor del primero. Aunque scc rastreó ~86.000 archivos frente a los ~67.000 de mezura, la diferencia de tiempo seguía siendo demasiado grande para justificarla solo con ese 28% extra de ficheros.

En lugar de leer el código de mezura, decidió observarlo desde fuera usando strace -f -c para contar las llamadas al sistema. Los números revelan por qué scc se quedaba atrás: mientras mezura realiza unas 514.000 llamadas para procesar sus archivos, scc genera cerca de 1,34 millones — casi 2,6 veces más— para contar un 28% más de archivos. El sospechoso principal era la llamada epoll_ctl: scc la invoca 95.898 veces, y 95.897 terminan en error. Le seguían fcntl con 383.594 llamadas y newfstatat con 286.428.

La causa raíz estaba en la arquitectura del pipeline de scc. Un único goroutine se encargaba de la fase de stat (comprobación de tamaño, simbólicos, exclusiones, detección de lenguaje), mientras que el resto del procesamiento estaba paralelizado. Ese cuello de botella mantenía la cola de archivos potenciales siempre llena y la de listos para contar vacía. Además, scc llama a os.Open una vez por archivo, y en Linux eso implica registrar el descriptor en el poller de Go, algo que el kernel rechaza para archivos regulares, generando ese aluvión de errores.

La solución fue doble: paralelizar la fase de stat con varios goroutines y evitar la llamada innecesaria al poller (por ejemplo, usando directamente openat vía syscall). Tras el cambio, las llamadas futex cayeron de unas 134.000 a unas 5.500, y el tiempo total bajó unos 160 ms. De paso, se corrigieron algunos bugs de concurrencia en newFileJob.

La lección es práctica: cuando una herramienta presume de velocidad, merece la pena medirla uno mismo y, si te gana, no darse por vencido. Un vistazo a las llamadas al sistema con strace puede indicar exactamente dónde está perdiendo tu programa el tiempo. En este caso, el autor encontró un defecto de diseño y lo arregló, mejorando scc para todos sus usuarios.