Bazı gerçek hız istiyorsanız:
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;
İnanılmaz derecede hızlı bir sözde tek astar.
Basit bir test Core i7 CPU 870 @ 2.93GHz’de 600 MB / sn’den fazla olduğunu gösteriyor:
$ 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
Sıralama içeren çözümlerden farklı olarak, bu, dosyanız raminizden çok daha büyükse, çok yararlı olan sabit (4K) bellekte çalışır.
Ve elbette, biraz dirsek yağıyla, 0.7 saniye tıraş oluruz:
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;
1.1GB / sn'nin üzerindeki ağlar:
real 0m0.943s
user 0m0.798s
sys 0m0.134s
Karşılaştırma için, bu sayfadaki bir tür hız sözü vermiş gibi görünen diğer çözümlerden bazılarını test ettim.
sed
/ awk
Çözüm yiğit çaba, ancak 30 saniye sonra öldü. Böyle basit bir regex ile, bunun sed'de bir hata olmasını bekliyorum (GNU sed sürüm 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
Perl yöntemi de umut verici görünüyordu, ancak 7 dakika çalıştırdıktan sonra pes ettim
time perl -e 'while (<>) {$c{$&}++ while /./g} print "$c{$_} $_\n" for keys %c' < bigdna
^C
real 7m44.161s
user 4m53.941s
sys 2m35.593s