Wenn Sie eine echte Geschwindigkeit wollen:
echo 'int cache[256],x,y;char buf[4096],letters[]="tacgn-"; int main(){while((x=read(0,buf,sizeof buf))>0)for(y=0;y<x;y++)cache[(unsigned char)buf[y]]++;for(x=0;x<sizeof letters-1;x++)printf("%c: %d\n",letters[x],cache[letters[x]]);}' | gcc -w -xc -; ./a.out < file; rm a.out;
Ist ein unglaublich schneller Pseudo-One-Liner.
Ein einfacher Test zeigt, dass es auf meiner Core i7-CPU 870 bei 2,93 GHz etwas mehr als 600 MB / s gibt:
$ du -h bigdna
1.1G bigdna
time ./a.out < bigdna
t: 178977308
a: 178958411
c: 178958823
g: 178947772
n: 178959673
-: 178939837
real 0m1.718s
user 0m1.539s
sys 0m0.171s
Im Gegensatz zu Sortierlösungen wird diese im konstanten Speicher (4 KB) ausgeführt, was sehr nützlich ist, wenn Ihre Datei viel größer als Ihr RAM ist.
Und natürlich können wir mit ein wenig Ellbogenfett 0,7 Sekunden abschneiden:
echo 'int cache[256],x,buf[4096],*bp,*ep;char letters[]="tacgn-"; int main(){while((ep=buf+(read(0,buf,sizeof buf)/sizeof(int)))>buf)for(bp=buf;bp<ep;bp++){cache[(*bp)&0xff]++;cache[(*bp>>8)&0xff]++;cache[(*bp>>16)&0xff]++;cache[(*bp>>24)&0xff]++;}for(x=0;x<sizeof letters-1;x++)printf("%c: %d\n",letters[x],cache[letters[x]]);}' | gcc -O2 -xc -; ./a.out < file; rm a.out;
Netze mit etwas mehr als 1,1 GB / s bei:
real 0m0.943s
user 0m0.798s
sys 0m0.134s
Zum Vergleich habe ich einige der anderen Lösungen auf dieser Seite getestet, die ein gewisses Geschwindigkeitsversprechen zu haben schienen.
Die sed
/ awk
solution unternahm eine tapfere Anstrengung, starb jedoch nach 30 Sekunden. Bei einem so einfachen regulären Ausdruck erwarte ich, dass dies ein Fehler in sed ist (GNU sed Version 4.2.1):
$ time sed 's/./&\n/g' bigdna | awk '!/^$/{a[$0]++}END{for (i in a)print i,a[i];}'
sed: couldn't re-allocate memory
real 0m31.326s
user 0m21.696s
sys 0m2.111s
Die Perl-Methode schien ebenfalls vielversprechend, aber ich gab auf, nachdem ich sie 7 Minuten lang ausgeführt hatte
time perl -e 'while (<>) {$c{$&}++ while /./g} print "$c{$_} $_\n" for keys %c' < bigdna
^C
real 7m44.161s
user 4m53.941s
sys 2m35.593s