Ho fatto un rapido benchmark sulle risposte esistenti che
- usa solo strumenti standard (scusami per cose come
lua
o rocket
),
- sono veri e propri liner,
- sono in grado di aggiungere enormi quantità di numeri (100 milioni) e
- sono veloci (ho ignorato quelli che hanno impiegato più di un minuto).
Ho sempre aggiunto i numeri da 1 a 100 milioni, fattibile sulla mia macchina in meno di un minuto per diverse soluzioni.
Ecco i risultati:
Pitone
:; seq 100000000 | python -c 'import sys; print sum(map(int, sys.stdin))'
5000000050000000
# 30s
:; seq 100000000 | python -c 'import sys; print sum(int(s) for s in sys.stdin)'
5000000050000000
# 38s
:; seq 100000000 | python3 -c 'import sys; print(sum(int(s) for s in sys.stdin))'
5000000050000000
# 27s
:; seq 100000000 | python3 -c 'import sys; print(sum(map(int, sys.stdin)))'
5000000050000000
# 22s
:; seq 100000000 | pypy -c 'import sys; print(sum(map(int, sys.stdin)))'
5000000050000000
# 11s
:; seq 100000000 | pypy -c 'import sys; print(sum(int(s) for s in sys.stdin))'
5000000050000000
# 11s
awk
:; seq 100000000 | awk '{s+=$1} END {print s}'
5000000050000000
# 22s
Incolla & Bc
Questo ha esaurito la memoria sulla mia macchina. Ha funzionato per metà delle dimensioni dell'input (50 milioni di numeri):
:; seq 50000000 | paste -s -d+ - | bc
1250000025000000
# 17s
:; seq 50000001 100000000 | paste -s -d+ - | bc
3750000025000000
# 18s
Quindi immagino che ci sarebbero voluti circa 35 secondi per i 100 milioni di numeri.
Perl
:; seq 100000000 | perl -lne '$x += $_; END { print $x; }'
5000000050000000
# 15s
:; seq 100000000 | perl -e 'map {$x += $_} <> and print $x'
5000000050000000
# 48s
Rubino
:; seq 100000000 | ruby -e "puts ARGF.map(&:to_i).inject(&:+)"
5000000050000000
# 30s
C
Per fare un confronto, ho compilato la versione C e ho provato anche questo, solo per avere un'idea di quanto siano lente le soluzioni basate su strumenti.
#include <stdio.h>
int main(int argc, char** argv) {
long sum = 0;
long i = 0;
while(scanf("%ld", &i) == 1) {
sum = sum + i;
}
printf("%ld\n", sum);
return 0;
}
:; seq 100000000 | ./a.out
5000000050000000
# 8s
Conclusione
C è ovviamente il più veloce con 8s, ma la soluzione Pypy aggiunge solo un overhead molto piccolo di circa il 30% a 11s . Ma, per essere onesti, Pypy non è esattamente standard. La maggior parte delle persone ha solo CPython installato che è significativamente più lento (22s), esattamente come la popolare soluzione Awk.
La soluzione più veloce basata su strumenti standard è Perl (15s).