Botón para abrir el Menú Botón para cerrar el Menú
Logo da empresa Alura
Iniciar Sesión Nuestros Planes
Formaciones Conoce a Luri
  • Programación _
  • Front End _
  • Data Science _
  • DevOps _
  • Innovación y Gestión _
Artículos de Tecnología > Programación

¿Qué es compilación y cuál es el rol de los compiladores?

Leonardo Sartorello
Leonardo Sartorello
07/05/2023

Compartir

Imagem de capa

Cuando creamos una aplicación, generalmente solo prestamos atención a nuestro código o bibliotecas, y no nos importa cómo se ejecutará, compilará o interpretará ese código.

Imagem01

Ambas opciones tienen sus ventajas y desventajas, principalmente en cuanto a la distribución y rendimiento de nuestro código. Un código compilado está hecho para un solo sistema, por lo que si lo vamos a hacer disponible para más de un sistema, tendremos que mantener un código binario para cada uno. Por otro lado, el código interpretado se puede distribuir fácilmente entre múltiples sistemas, pero no funciona tan bien como el código compilado. Los lenguajes compilados como C, C++, Fortran, Delphi y Pascal generalmente funcionan mejor, mientras que los lenguajes interpretados como C#, JavaScript, Python, PHP y Ruby tienden a ser más fáciles de portar, lo que les permite ejecutarse en múltiples sistemas.

¿Qué es un compilador y cuáles son sus principales tareas?

El compilador es un programa que lee y analiza el código fuente de la aplicación, es decir, el código que escribimos, y genera un código binario que se puede ejecutar desde él. Los compiladores suelen ser programas con lógica compleja, ya que utilizan muchas técnicas para acelerar la aplicación y reducir los requisitos del sistema donde se ejecutará la aplicación. Las principales tareas de los compiladores son:

Preprocesamiento

Este es el primer paso para un compilador, donde se incluye el código fuente, se analizan los errores de sintaxis y se vuelven a emplear y procesar macros o definiciones. Este paso se da mucho en lenguajes como C y C++.

Compilacion

En este paso, el código fuente se convierte en código ensamblador, muy similar al código máquina o código binario. Sin embargo, todavía contiene referencias a archivos externos, por lo que no se puede utilizar.

Assembly Con el código Assembly listo, pasa por un convertidor, llamado ensamblador, para convertirse en un código binario hecho exclusivamente para un solo sistema.

Linker

Esta es la última etapa del compilador, donde las bibliotecas, ya compiladas, se agregan a nuestro código binario, lo que permite la creación de un archivo binario ejecutable.

Imagem02

Algunos compiladores contienen más tareas, como optimización y detección de errores comunes, entre otras opciones, dejando que el creador del compilador las defina todas, así podemos tener varios compiladores para un mismo lenguaje, que pasan por diferentes procesos y terminan hasta generar códigos binarios en distintos lenguajes, como es el caso de los lenguajes C y C++, que cuentan con más de 30 compiladores diferentes.

Código binário

Los procesadores no entienden las palabras, solo contienen circuitos que pueden realizar acciones como matemáticas y leer y escribir en la memoria. Entonces, para usar estas operaciones, debemos elegir los circuitos, también llamados instrucciones, y luego pasarles los parámetros sobre los que queremos actuar.

Podemos pensar en las instrucciones como si fueran funciones predefinidas que aceptan algunos argumentos, y el trabajo del compilador es hacer que todo el código sea ejecutado por estas funciones. Los circuitos se activan, usan y borran durante la ejecución de un programa porque el archivo binario de este programa contiene las operaciones que queremos realizar, siempre usando números binarios, 0 y 1.

Usemos un ejemplo para que sea un poco más fácil visualizar los códigos binarios y su ejecución en los circuitos del procesador. Usando C para escribir el código fuente, tenemos:

int main()

{ // función main con un retorno de tipo numérico

int x; // creación de variables x

x = 3; // establece el valor de x

}

Cuando lo pasemos por un compilador, tendremos un archivo binario que se verá así:

111001011000100101001000010101010000001111111100010001011100011110111000000000000000000000000000000000000000000000000000000000001100001101011101

Este es el contenido de un archivo binario. Para ver o editar este contenido, necesitamos un editor especial, ya que los editores de texto intentan poner este archivo en alguna codificación, como UTF-8 o ASCII, para mostrarnos los caracteres.

Podemos ver lo que significan estos números al traducir el archivo binario a Assembly:

pushq %rbp //inicia el programa con la operación de 64-bit

movq %rsp, %rbp //transfiere el valor presente en rsp al comienzo del programa

movl $3, -4(%rbp) //creación de variables y asignación de valor 3

movl $3, $eax //transfiere el valor 3 a la posición eax

popq %eax //copiar el valor 3 al final del programa

ret // cierra el programa

La primera palabra de cada línea es la instrucción que se debe activar dentro del procesador, una vez que tengamos los parámetros. Como es mucho más laborioso escribir en código ensamblador o binario, generalmente usamos un lenguaje de nivel superior, como C, C + +.

Además, el código binario varía de un sistema a otro, por lo que los códigos binarios creados para Windows no funcionan en Linux, ya que el sistema operativo no los reconoce como ejecutables.

También tenemos diferentes arquitecturas de procesadores, como x86-x64, que se usa en la mayoría de las computadoras, ARM, que se usa en teléfonos móviles y recientemente en algunos servidores, y RISC-V, que está ganando terreno en las aplicaciones de IoT y está tratando de ingresar a otras mercados. Cada una de estas arquitecturas tiene diferentes códigos binarios, ya que contienen diferentes circuitos, la x86-x64 contiene aproximadamente 3700 instrucciones, mientras que el ARM tiene aproximadamente 500 instrucciones y el RISC-V con 47 instrucciones.

Lenguajes interpretados

Si bien la compilación generalmente hace que los programas sean eficientes en términos de consumo de recursos, dificulta la transferencia de código entre múltiples sistemas. Pensando en cómo solucionar esto, se crearon lenguajes que no se compilan durante el desarrollo, sino durante la ejecución, lenguajes interpretados.

Los lenguajes interpretados no necesitan pasar por el proceso de compilación, lo que acelera enormemente la velocidad de desarrollo, ya que los programas grandes y complejos pueden tardar más de 30 minutos en completarse y todo el programa debe recompilarse con cada cambio en el código.

El proceso de interpretación del lenguaje consta de varios pasos y muchos se realizan dentro de máquinas virtuales, como es el caso de python. Sin embargo, todavía es necesario usar solo las instrucciones presentes en la máquina física y, por lo tanto, los intérpretes terminan compilando el código, pero lo hacen durante la ejecución.

Algunas lenguajes interpretadas son PHP, JavaScript y Python, cada una con desarrollo enfocado, pero no exclusivo, a un público objetivo, como JavaScript en el Front-end con navegadores y en el Back-end con NodeJS o Deno.

Los lenguajes interpretados son más fáciles de trasladar de un sistema a otro, pero necesitan una capa intermedia para traducir los comandos del programa a código binario, como el intérprete de Python a Python y el navegador a JavaScript. Este proceso crea una barrera con respecto al desempeño de estos lenguajes.

En algunos casos, algunas bibliotecas funcionan mejor que el idioma nativo porque están escritas en un lenguaje compilado, como es el caso de las bibliotecas numPy y sciPy para Python.

En general, elegir un lenguaje interpretado permite que tu código se ejecute en varias computadoras, con diferentes sistemas o configuraciones, y también acelera mucho el período de desarrollo, pero tiende a ser más lento y consumen más de la máquina en la que se ejecutan.

Entonces, para algunas aplicaciones se prefieren lenguajes interpretados, como es el caso de JavaScript para ejecutar código en el navegador, ya que un lenguaje compilado necesitaría tener varias versiones, dependiendo del sistema cliente. Por tanto, podrían existir incompatibilidades si no se transfiere la configuración del cliente, por motivos de privacidad o seguridad.

También se recomienda comenzar a estudiar programación utilizando lenguajes interpretados, ya que no se dedica mucho tiempo a compilar cada cambio de código, lo que hace que la experiencia sea más rápida y fluida.

Java

Java es un lenguaje diferente a la mayoría en cuanto a ser compilado o interpretado, es interpretado y compilado al mismo tiempo. Esto permite que Java se ejecute en muchos dispositivos diferentes con un solo ejecutable y una sola compilación y, además, no tiene una gran penalización de tiempo de ejecución.

Como Java se ejecuta dentro de la Máquina Virtual de Java (JVM), o la Máquina Virtual de Java, puede considerarse un lenguaje interpretado. Al mismo tiempo, la JVM no utiliza código fuente, sino una versión compilada para él.

Con esta técnica es posible ejecutar el código en cualquier sistema que soporte la JVM y, al mismo tiempo, no tiene una penalización de rendimiento muy alta a la hora de la ejecución, como ocurre con otros lenguajes interpretados, ya que el trabajo de optimización del código fuente ya se ha creado y el archivo generado está más cerca del lenguaje de máquina.

Al mismo tiempo, necesitamos el intérprete que los lenguajes compilados no necesitan, y también dedicamos tiempo a cada compilación, lo que ralentiza el desarrollo.

Conclusión

El compilador tiene un trabajo muy importante tanto en los lenguajes que se compilan como en los que se interpretan, ya que todos los comandos deben ser transformados a código binario para poder ser procesados. Los primeros compiladores, que estaban escritos en lenguaje ensamblador, permitieron crear nuevos programas y compiladores mejores y más complejos, acelerando el desarrollo y automatizando la tarea de analizar y traducir la lógica del programa en instrucciones de máquina.

img-autor

Leonardo Sartorello.

Leonardo es desarrollador y capacitador en Alura con un enfoque principal en DevOps y Cloud, con experiencia en virtualización, contenedorización, infraestructura como código e IoT.

Traducido para Alura Latam por Rafaela Rocha.

Artículo Anterior
Tipos de Autenticación: Contraseña, Token, JWT, Dos Factores y Más.
Siguiente Artículo
¿Qué son los algoritmos? ¿Para qué sirven y cómo se utilizan en la programación?

Ver otros artículos sobre Programación

Navegación

  • Planes
  • Instructores
  • Blog
  • Política de privacidad
  • Términos de uso
  • Sobre nosotros
  • Preguntas frecuentes

¡CONTÁCTANOS!

  • ¡Quiero entrar en contacto!

Blog

  • Programación
  • Data Science
  • Front End
  • Innovación y Gestión
  • DevOps

AOVS Sistemas de Informática S.A CNPJ 05.555.382/0001-33

SÍGUENOS EN NUESTRAS REDES SOCIALES

YouTube Facebook Instagram Linkedin Whatsapp Spotify

NOVEDADES Y LANZAMIENTOS

Aliados

  • Programa de aceleração Scale-Up Endeavor
  • En Alura somos unas de las Scale-Ups seleccionadas por Endeavor, programa de aceleración de las empresas que más crecen en el país.
  • Growth Academy 2021 do Google For Startups
  • Fuimos unas de las 7 startups seleccionadas por Google For Startups en participar del programa Growth Academy en 2021
Alura

Powered by

Caelum

AOVS Sistemas de Informática S.A CNPJ 05.555.382/0001-33

SÍGUENOS EN NUESTRAS REDES SOCIALES

YouTube Facebook Instagram Linkedin Whatsapp Spotify

Cursos

Cursos de Programación
Lógica de Programación | Java
Cursos de Front End
HTML y CSS | JavaScript | React
Cursos de Data Science
Data Science | Machine Learning | Excel | Base de Datos | Data Visualization | Estadística
Cursos de DevOps
Docker | Linux
Cursos de Innovación y Gestión
Transformación Ágil | Marketing Analytics

Alura

  • Educação em Tecnologia

    • logo fiap FIAP
    • logo casa do codigo Casa do Código
    • logo pm3 PM3 - Cursos de Produto
  • Mais Alura

    • logo alura start START BY Alura
    • logo alura lingua Alura Língua
    • logo alura para empresas Alura Para Empresas
    • logo alura latam Alura LATAM
  • Comunidade

    • logo tech guide Tech Guide
    • logo 7 days of code 7 days of code
    • logo Hipsters ponto Jobs Hipsters ponto Jobs
  • Podcasts

    • logo Hipster Network Hipster Network
    • logo Hipsters ponto Tech Hipsters ponto Tech
    • logo Dev sem fronteiras Dev sem Fronteiras
    • logo Like a Boss Like a Boss
    • logo IA Sob Controle IA Sob Controle
    • logo Mesa de Produto Mesa de Produto
    • logo Decode Decode
    • logo FIAPCast FIAPCast