Post

¿Por qué C++?

Por qué usamos C++ en lugar de otros lenguajes como Rust, Python, Java, etc.

Tabla de Contenidos:

¿Qué es C++?

C++ es un lenguaje compilado de alto nivel inventado por Bjarne Stroustrup en 1979 para extender la funcionalidad de C, incorporando el paradigma de la programación orientada a objetos a través de clases. Su ventaja sobre otros lenguajes radica en su velocidad y en la amplia funcionalidad gracias a funciones y algoritmos integrados en la librería estandard STL . Está entre en los 3 lenguajes más populares según TIOBE

¿Qué buscamos de un lenguaje de programación?

  1. Presencia en plataformas y competencias
  2. Velocidad de ejecución
  3. Funciones, algoritmos, estructuras de datos en la librería estándar
  4. Sintaxis y velocidad de Entrada/Salida (I/O)

1. Presencia en plataformas y competencias

  • Lenguajes permitidos en Codeforces

    • C, C++, C#, D, Go, Haskell, Java, Kotlin, OCaml, Delphi, Pascal, Perl, PHP, Python, Ruby, Rust, Scala, JavaScript y Node.js
  • Lenguajes permitidos en el ICPC

    • C, C++, Java, Kotlin y Python

Comparación de Lenguajes permitidos

LenguajeVentajasDesventajas
Java- Gestión de memoria automática
- Gran cantidad de librerías
- Consumo alto de memoria
- E/S lenta
- Sintaxis extensa y por clases
Kotlin- Sintaxis moderna y concisa
- Interoperabilidad con Java
- Comunidad y recursos más limitados
Python3- Sintaxis simple y legible
- Gran cantidad de librerías
- Lento en la ejecución
- Gestión de memoria no tan eficiente
C- Muy rápido y eficiente en términos de rendimiento
- Soporta el uso de Macros y Alias
- Manejo de memoria manual
- Sin varias estructuras de datos
C++- Muy rápido y eficiente
- Amplia biblioteca estándar STL
- Interoperabilidad con C
- Complejidad en la gestión de memoria
- Curva de aprendizaje pronunciada

2. Velocidad de ejecución

Resultados normalizados de velocidad y consumo por lenguaje

  • por Pereiraa, R. et al.
xychart-beta
    title "Velocidad por Lenguaje"
    x-axis ["C", "C++", "Rust", "Java", "Python"]
    y-axis "Tiempo (ms)"
    bar [1.00, 1.56 , 1.04, 1.89, 71.90]
    line [1.00, 1.56 , 1.04, 1.89, 71.90]
xychart-beta
    title "Consumo Energético por Lenguaje"
    x-axis ["C", "C++", "Rust", "Java", "Python"]
    y-axis "Consumo Energético (J)"
    bar [1.00, 1.34, 1.03, 1.98, 75.88]
    line[1.00, 1.34, 1.03, 1.98, 75.88]
xychart-beta
    title "Consumo de Memoria por Lenguaje"
    x-axis ["C", "C++", "Rust", "Java", "Python"]
    y-axis "Memory (Mb)"
    bar [1.17, 1.34, 1.54, 6.01, 2.80]

Ranking de velocidad por lenguaje ejecutando el algoritmo de la criba de Eratóstenes

  • por Plummer, D.
xychart-beta
    title "Criba de Eratóstenes"
    x-axis ["C", "C++", "Rust", "Java", "Kotlin", "Python"]
    y-axis "Aparición en R  anking"
    bar [3, 1, 2, 4, 5, 6]

3. Funciones, algoritmos, estructuras de datos en la librería estándar

  • C
    • Estructuras de datos: Arreglos (vectores) y cadenas. No incluye estructuras de datos avanzadas.
    • Algoritmos: No incluye algoritmos, la implementación de cada uno es manual.
  • C++
    • Estructuras de datos: vector, list, map, set, stack, queue, etc.
    • Algoritmos: sort, find, binary_search, entre otros.
  • Rust
    • Estructuras de datos: Vec, LinkedList, HashMap, BTreeMap, HashSet, BTreeSet. No tiene stack ni queue específicos, pero se pueden implementar.
    • Algoritmos: sort, iter, filter, map, entre otros.
  • Java
    • Estructuras de datos: ArrayList, LinkedList, HashMap, TreeMap, HashSet, TreeSet, Stack, PriorityQueue.
    • Algoritmos: sort, binarySearch, shuffle, entre otros.
  • Kotlin
    • Estructuras de datos: List, MutableList, Map, MutableMap, Set, MutableSet. No tiene stack ni queue específicos, pero se pueden implementar.
    • Algoritmos: sort, filter, map, reduce, entre otros.
  • Python3
    • Estructuras de datos: list, tuple, dict, set, frozenset, deque (para stack y queue).
    • Algoritmos: sorted, map, filter, reduce, heapq, bisect, entre otros.

4. Sintaxis y velocidad de Entrada/Salida (I/O)

C

1
2
3
4
5
6
7
8
#include <stdio.h>
int main() {
    int n;
    scanf("%i", &n); // Entrada de n
    printf("%i",n);  // Salida de n
    return 0;
}

con buffers

1
2
3
4
5
6
7
8
9
#include <stdio.h>
int main() {
    char buffer[1000];
    int n;
    snprintf(buffer, sizeof(buffer), "%d\n", n); // entrada de n
    fputs(buffer, stdout);                       // Salida de n
    return 0;
}

C++

1
2
3
4
5
6
7
8
9
10
#include <bits/stdc++.h>
using namespace std;
int main(){
    ios::sync_with_stdio(0); cin.tie(0);
    int n; 
    cin >> n;  // entrada de n
    cout << n; // Salida de n
    return 0;
}

Rust

1
2
3
4
5
6
7
8
9
10
11
use std::io::{self, BufRead, Write, BufWriter};
fn main() -> io::Result<()> {
    let stdin = io::stdin();
    let stdout = io::stdout();
    let mut stdout = BufWriter::new(stdout.lock());
    let mut input = String::new();
    stdin.lock().read_line(&mut input).unwrap();
    let n: i32 = input.trim().parse().unwrap(); // entrada de n
    writeln!(stdout, "{}", n)?;         // salida de n
    Ok(())
}

Java

con BufferedReader y PrintWriter

1
2
3
4
5
6
7
8
9
10
11
12
import java.io.*;
import java.util.*;
public class Main {
	public static void main(String[] args) throws Exception {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            PrintWriter pw = new PrintWriter(System.out);
            StringTokenizer st = new StringTokenizer(br.readLine());
            int n = Integer.parseInt(st.nextToken());  // entrada de n
            pw.println(n);                             // salida de n
            pw.close();
	}
}

más veloz con BufferedReader directo de InputStream

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import java.io.*;
import java.util.*;
class FastIO extends PrintWriter {
	private InputStream stream;
	private byte[] buf = new byte[1 << 16];
	private int curChar;
	private int numChars;
	public FastIO() { this(System.in, System.out); }
	public FastIO(InputStream i, OutputStream o) { super(o); stream = i; }
	public FastIO(String i, String o) throws IOException { 
        super(new FileWriter(o)); stream = new FileInputStream(i); }
	private int nextByte() { 
		if (numChars == -1) { throw new InputMismatchException(); }
		if (curChar >= numChars) { curChar = 0;
			try { numChars = stream.read(buf); }
            catch (IOException e) { throw new InputMismatchException(); }
			if (numChars == -1) { return -1; } }
		return buf[curChar++]; }
	public String next() { int c; 
		do { c = nextByte(); } while (c <= ' ');
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = nextByte();
		} while (c > ' ');
		return res.toString();
	}
	public int nextInt() {  
		int c;
		do { c = nextByte(); } while (c <= ' ');
		int sgn = 1;
		if (c == '-') { sgn = -1; c = nextByte(); }
		int res = 0;
		do { 
			if (c < '0' || c > '9') { throw new InputMismatchException(); }
			res = 10 * res + c - '0'; c = nextByte();
		} while (c > ' ');
		return res * sgn;
	}
	public double nextDouble() { return Double.parseDouble(next()); }
}
public class Main {
	public static void main(String[] args) throws Exception {
            FastIO io = new FastIO();
            int n = io.nextInt(); // entrada de n
            io.println(n);        // salida de n 
            io.close();
	}
}

Kotlin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.io.*
import java.util.*
@JvmField val writer = PrintWriter(System.out)
@JvmField val reader = BufferedReader(InputStreamReader(System.`in`))
@JvmField var tokenizer = StringTokenizer("")
private fun read(): String {
    while (!tokenizer.hasMoreTokens()) {
        tokenizer = StringTokenizer(reader.readLine())
    }
    return tokenizer.nextToken()
}
fun main() { 
    var n = read().toInt() // entrada de n
    writer.println(n)       // salida de n
    writer.flush()          
}  

Python3

1
2
3
4
5
6
7
8
9
import sys
read = sys.stdin.readline
write = sys.stdout.write
def main():
    n = int(read()) # entrada de n
    write(f"{n}\n") # salida de n

if __name__ == "__main__":
    main()

Conclusión

Usamos C++ debido a que cumple con las cuatro criterios que propusimos para un lenguaje eficiente y versátil, C++ cuenta con presencia en todas las plataformas y Competencias donde ofrece una de las mejores velocidades de ejecución y eficiencia energética entre los lenguajes permitidos.

La librería estándar STL de C++ es uno de los proporciona una amplia gama de estructuras de datos y algoritmos eficientes, lo que facilita la implementación de soluciones complejas sin necesidad de bibliotecas adicionales. Aunque la sintaxis de C++ puede ser más compleja en comparación con python, sigue siendo más concisa que la de Java por ejemplo. Su capacidad para manejar operaciones de entrada y salida de manera eficiente, evitaran tener un TLE (Time Limit Exceeded).

En resumen, la combinación de velocidad, amplia funcionalidad, y la capacidad de integración hace de C++ una elección muy fuerte y efectiva para distintas aplicaciones, desde programación competitiva hasta desarrollo de software a gran escala.

Referencias

Esta publicación tiene la licencia CC BY 4.0 del autor.

Diseñado con ❤️ por Ariel Parra.

© CPC-GALLOS. Algunos derechos reservados.

Hecho con Jekyll usando el tema Chirpy