Benchmarks

¿Qué es?

Es una técnica utilizada para medir el rendimiento de un sistema o componente del mismo.

La palabra benchmark es un anglicismo traducible al español como comparativa.

Es en el campo informático donde su uso está más ampliamente extendido.

Es el resultado de la ejecución de un programa informático o un conjunto de programas en una máquina, con el objetivo de estimar el rendimiento de un elemento concreto, y poder comparar los resultados con máquinas similares.

La elección de las condiciones bajo la cual dos sistemas distintos pueden compararse entre sí es especialmente ardua, y la publicación de los resultados suele ser objeto de candentes debates cuando éstos se abren a la comunidad.

Cualidades

  • Comprobar si las especificaciones de los componentes están dentro del margen propio del mismo
  • Maximizar el rendimiento con un presupuesto dado
  • Minimizar costos manteniendo un nivel máximo de rendimiento
  • Obtener la mejor relación costo/beneficio (con un presupuesto o unas exigencias dadas)

Tipos

Sintéticos vs Aplicaciones

  • Sintéticos: están especialmente diseñadas para medir el rendimiento de un componente individual de un ordenador, normalmente llevando el componente escogido a su máxima capacidad.
  • Aplicaciones: herramientas basadas en aplicaciones reales, simulan una carga de trabajo para medir el comportamiento global del equipo.

Bajo nivel vs Alto nivel

  • Test de Bajo nivel: miden directamente el rendimiento de los componentes
    Ejemplo: el reloj de la CPU, los tiempos de la DRAM y de la caché SRAM, tiempo de acceso medio al disco duro, latencia, tiempo de cambio de pista, etc.
  • Test de Alto nivel: Están más enfocados a medir el rendimiento de la combinación componente/controlador/SO de un aspecto específico del sistema
    Ejemplo: Velocidad de compresión zip.

Otros

  • Consumo de energía
  • Cumplimiento con estándares ambientales, contenido de materiales y manejo del final del ciclo de vida del producto
  • Disipación de calor
  • De juguete: detectar y medir componentes básicos de un computador
  • Redes
  • Reducción de ruido
  • Trabajo compartido: mide el rendimiento en las modernas tecnologías de distribución de procesos
  • Servidores
  • Soporte técnico

En software...

Se suelen realizar benchmarks sobre servidores web para evaluar la cantidad de respuestas por segundo que pueden entregar o lo que demora una respuesta.

También sobre frameworks, ya sea para evaluar una parte del mismo o el framework entero.

Incluso, se utilizan para evaluar pequeños trozos de código de un sistema que son importantes ya que forman parte del núcleo. Generalmente, todo código que se ejecuta muy frecuentemente. Se miden desde funciones enteras hasta sentencias de una sola línea.

¡Importante!

Es fundamental que el entorno en donde se realizan los benchmarks esté totalmente aislado y no influya en los resultados de los tests. Tampoco debe cambiar de estado entre ejecuciones de los tests.

Se deben realizar múltiples mediciones y luego obtener un promedio de ellas.

Ejemplos

Lenguajes de Programación

jsPerf aims to provide an easy way to create and share test cases, comparing the performance of different JavaScript snippets by running benchmarks.

Permite crear y compartir tests en Javascript.

function hola(param) {
    console.log(param);
}

hola('hola');

Otro ejemplo

const hola = function(param) {
    console.log(param);
}

hola('hola');

¿Para qué me sirve conocer esto?

  • Como desarollador de Javascript, para optimizar el código del sistema que esté desarrollando en aquellas partes que sean críticas.
  • Como desarrollador del motor V8 (lo que interpreta y ejecuta Javascript), para entender qué partes del motor deben ser optimizadas o reemplazadas.

Alternativas:

jsbench.github.io (web)

benchmarkjs.com (librería)

NodeJS

Javascript del lado del servidor

Muchos benchmarks son realizados por personas que no tienen en cuenta el entorno en que se ejecutan o que se dejan llevar por el fanatismo.

Brindan poca información de cómo realizaron los tests y con qué herramientas  específicas de cada lenguaje (librerías, frameworks, intérpretes o compiladores, étc.).

 

Los benchmarks no definen si una herramienta es mejor que otra, ya que solamente consideran algunos puntos importantes aislando los demás, y esto determina que una herramienta funciona mejor que otra solamente en los casos que las mediciones evaluaron.

Servidor Web

API RESTful

¿Qué se va a medir?

La cantidad de respuestas por segundo de una API hecha con NodeJS.

Se utiliza la librería nativa http y dos frameworks:

¿Con qué herramienta se va a medir?

¿Cuál es el entorno sobre el que se realiza el benchmark?

  • Sistema operativo: ArchLinux (kernel 4.11.3-1-ARCH)
  • Procesador: Intel Core i7-7700
  • Memoria RAM: 16 GB DDR4
  • Versión de NodeJS: v8.0.0
  • Versión de Express: 4.15.4
  • Versión de Restify: 5.1.0
const http = require('http');
const port = 3000;

const requestHandler = (request, response) => {
    response.end('Hello Node.js Server!');
}

const server = http.createServer(requestHandler);

server.listen(port, () => {
    console.log(`Escuchando en el puerto ${port}`);
});

Con HTTP nativo

const express = require('express');
const app = express();

app.get('/', function (req, res) {
    res.send('Administración de Recursos');
});

app.listen(3000, function () {
    console.log('Escuchando en el puerto 3000');
});

Con Express

const restify = require('restify');

var server = restify.createServer();
server.get('/', function(req, res, next) {
    res.send('Administración de Recursos');
    next();
});

server.listen(3000, function() {
    console.log('Escuchando en el puerto 3000');
});

Con Restify

Se corre un benchmarking, levantando los servidores con los distintos frameworks uno a uno.

$ ab -r -n 100000 -c 1000 http://localhost:3000/

Resultados

HTTP nativo

Server Hostname:        localhost
Server Port:            3000

Document Path:          /
Document Length:        27 bytes

Concurrency Level:      1000
Time taken for tests:   3.894 seconds
Complete requests:      100000
Failed requests:        0
Total transferred:      10200000 bytes
HTML transferred:       2700000 bytes
Requests per second:    25683.01 [#/sec] (mean)
Time per request:       38.936 [ms] (mean)
Time per request:       0.039 [ms] (mean, across all concurrent requests)
Transfer rate:          2558.27 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   21 162.5      0    3118
Processing:     1   10  33.6      7    1659
Waiting:        1   10  33.6      7    1659
Total:          2   31 182.8      7    3332

Express

Server Hostname:        localhost
Server Port:            3000

Document Path:          /
Document Length:        27 bytes

Concurrency Level:      1000
Time taken for tests:   27.256 seconds
Complete requests:      100000
Failed requests:        0
Total transferred:      22700000 bytes
HTML transferred:       2700000 bytes
Requests per second:    3668.87 [#/sec] (mean)
Time per request:       272.564 [ms] (mean)
Time per request:       0.273 [ms] (mean, across all concurrent requests)
Transfer rate:          813.31 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   35 205.7      0    3203
Processing:     8   65 910.1     12   26246
Waiting:        8   65 910.1     12   26246
Total:          9  100 985.8     12   27253

Restify

Server Hostname:        localhost
Server Port:            3000

Document Path:          /
Document Length:        29 bytes

Concurrency Level:      1000
Time taken for tests:   14.243 seconds
Complete requests:      100000
Failed requests:        0
Total transferred:      17300000 bytes
HTML transferred:       2900000 bytes
Requests per second:    7020.79 [#/sec] (mean)
Time per request:       142.434 [ms] (mean)
Time per request:       0.142 [ms] (mean, across all concurrent requests)
Transfer rate:          1186.13 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   44 223.0      0    3149
Processing:     8   33 401.2     11   13209
Waiting:        8   33 401.2     11   13209
Total:          9   77 499.7     11   14237

¡Gracias!

Benchmarks de API en NodeJS:
aboglioli/simple-node-frameworks-benchmarks

¡Gracias!

benchmarks

By Alan Boglioli

benchmarks

  • 327