Mi respuesta se basa en cómo funciona el enlazador dinámico de Linux/glibc/ELF, pero yo supongo que la respuesta general es el mismo para otras plataformas:
Hay una diferencia entre la primera llamada a un dinámicamente cargado símbolo y las próximas llamadas. La primera llamada es costosa, puede implicar muchos ciclos. Todas las otras llamadas son más o menos 1 - 2 instrucción de distancia.
La manera en que funciona es que el enlazador establece una entrada en la Tabla de vinculación de procedimientos que toma una dirección para esa función externa de la Tabla de compensación global. Al principio, llame a la dirección de los puntos GOT a un apéndice que ejecuta el enlazador dinámico para resolver la dirección real de la función en el archivo DLL. Esto puede llevar muchos ciclos, pero una vez que se hace una vez, el enlazador dinámico encaminará la entrada GOT para apuntar directamente a la función, por lo que la próxima vez que se llame al código PLT se llamará directamente a la función.
Aquí hay un enlace a una bastante buena caminata a través de este proceso: http://www.technovelty.org/linux/pltgot.html
posible duplicado de [arriba de la DLL] (http://stackoverflow.com/questions/4030043/overhead-of-dll) –