mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 06:09:22 +02:00
+ added k-nucleotide benchmark
git-svn-id: trunk@4871 -
This commit is contained in:
parent
adca49097e
commit
61d979808a
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -5104,6 +5104,7 @@ tests/bench/pi.c -text
|
|||||||
tests/bench/pi.pp svneol=native#text/plain
|
tests/bench/pi.pp svneol=native#text/plain
|
||||||
tests/bench/shootout/README.txt svneol=native#text/plain
|
tests/bench/shootout/README.txt svneol=native#text/plain
|
||||||
tests/bench/shootout/io/binarytrees-output.txt svneol=native#text/plain
|
tests/bench/shootout/io/binarytrees-output.txt svneol=native#text/plain
|
||||||
|
tests/bench/shootout/io/knucleotide-output.txt svneol=native#text/plain
|
||||||
tests/bench/shootout/io/moments.in -text
|
tests/bench/shootout/io/moments.in -text
|
||||||
tests/bench/shootout/io/moments.out -text
|
tests/bench/shootout/io/moments.out -text
|
||||||
tests/bench/shootout/io/recursive-output.txt svneol=native#text/plain
|
tests/bench/shootout/io/recursive-output.txt svneol=native#text/plain
|
||||||
@ -5152,8 +5153,10 @@ tests/bench/shootout/obsolete/wc.pp svneol=native#text/plain
|
|||||||
tests/bench/shootout/src/bench.c -text
|
tests/bench/shootout/src/bench.c -text
|
||||||
tests/bench/shootout/src/binarytrees.pp svneol=native#text/plain
|
tests/bench/shootout/src/binarytrees.pp svneol=native#text/plain
|
||||||
tests/bench/shootout/src/hello.pp svneol=native#text/plain
|
tests/bench/shootout/src/hello.pp svneol=native#text/plain
|
||||||
|
tests/bench/shootout/src/knucleotide.pp svneol=native#text/plain
|
||||||
tests/bench/shootout/src/nsieve.pp svneol=native#text/plain
|
tests/bench/shootout/src/nsieve.pp svneol=native#text/plain
|
||||||
tests/bench/shootout/src/recursive.pp svneol=native#text/plain
|
tests/bench/shootout/src/recursive.pp svneol=native#text/plain
|
||||||
|
tests/bench/shootout/src/simple_hash.pp svneol=native#text/plain
|
||||||
tests/bench/shootout/src/spectralnorm.pp svneol=native#text/plain
|
tests/bench/shootout/src/spectralnorm.pp svneol=native#text/plain
|
||||||
tests/bench/shootout/src/sumcol.pp svneol=native#text/plain
|
tests/bench/shootout/src/sumcol.pp svneol=native#text/plain
|
||||||
tests/bench/shortbench.pp svneol=native#text/plain
|
tests/bench/shortbench.pp svneol=native#text/plain
|
||||||
|
27
tests/bench/shootout/io/knucleotide-output.txt
Normal file
27
tests/bench/shootout/io/knucleotide-output.txt
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
A 30.284
|
||||||
|
T 29.796
|
||||||
|
C 20.312
|
||||||
|
G 19.608
|
||||||
|
|
||||||
|
AA 9.212
|
||||||
|
AT 8.950
|
||||||
|
TT 8.948
|
||||||
|
TA 8.936
|
||||||
|
CA 6.166
|
||||||
|
CT 6.100
|
||||||
|
AC 6.086
|
||||||
|
TC 6.042
|
||||||
|
AG 6.036
|
||||||
|
GA 5.968
|
||||||
|
TG 5.868
|
||||||
|
GT 5.798
|
||||||
|
CC 4.140
|
||||||
|
GC 4.044
|
||||||
|
CG 3.906
|
||||||
|
GG 3.798
|
||||||
|
|
||||||
|
562 GGT
|
||||||
|
152 GGTA
|
||||||
|
15 GGTATT
|
||||||
|
0 GGTATTTTAATT
|
||||||
|
0 GGTATTTTAATTTATAGT
|
176
tests/bench/shootout/src/knucleotide.pp
Normal file
176
tests/bench/shootout/src/knucleotide.pp
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
(* The Computer Language Shootout
|
||||||
|
http://shootout.alioth.debian.org/
|
||||||
|
|
||||||
|
contributed by Josh Goldfoot
|
||||||
|
modified by Vincent Snijders
|
||||||
|
*)
|
||||||
|
|
||||||
|
program knucleotide;
|
||||||
|
|
||||||
|
{$mode objfpc}{$I-}
|
||||||
|
|
||||||
|
(* simple_hash available from CVS *)
|
||||||
|
uses simple_hash, SysUtils, Strings, Math;
|
||||||
|
|
||||||
|
type
|
||||||
|
sorter = record
|
||||||
|
sequence : PChar;
|
||||||
|
num : longint;
|
||||||
|
end;
|
||||||
|
sorterArray = array of sorter;
|
||||||
|
|
||||||
|
function hash_table_size (fl : dword; buflen : dword): dword;
|
||||||
|
var
|
||||||
|
maxsize1, maxsize2, r : dword;
|
||||||
|
begin
|
||||||
|
maxsize1 := buflen - fl;
|
||||||
|
maxsize2 := 4;
|
||||||
|
while (fl > 1) and (maxsize2 < maxsize1) do
|
||||||
|
begin
|
||||||
|
fl := fl - 1;
|
||||||
|
maxsize2 := maxsize2 * 4;
|
||||||
|
end;
|
||||||
|
if maxsize1 < maxsize2 then
|
||||||
|
r := maxsize1
|
||||||
|
else
|
||||||
|
r := maxsize2;
|
||||||
|
hash_table_size := r;
|
||||||
|
end; { hash_table_size }
|
||||||
|
|
||||||
|
function generate_frequencies(fl: integer; buffer: PChar; buflen : longint): ht_pht;
|
||||||
|
var
|
||||||
|
reader : PChar;
|
||||||
|
i, bufend : longint;
|
||||||
|
nulled : char;
|
||||||
|
begin
|
||||||
|
if fl <= buflen then
|
||||||
|
begin
|
||||||
|
result := ht_create (hash_table_size (fl, buflen));
|
||||||
|
reader := buffer;
|
||||||
|
for i := 0 to buflen-fl do
|
||||||
|
begin
|
||||||
|
nulled := reader[fl];
|
||||||
|
reader[fl] := #0;
|
||||||
|
inc(ht_find_new (result, reader)^.val);
|
||||||
|
reader[fl] := nulled;
|
||||||
|
inc(reader);
|
||||||
|
end;
|
||||||
|
end else
|
||||||
|
result := nil;
|
||||||
|
end; { generate_frequencies }
|
||||||
|
|
||||||
|
procedure sortArray(var s : sorterArray; size:longint);
|
||||||
|
var
|
||||||
|
i,j : longint;
|
||||||
|
tmp : sorter;
|
||||||
|
begin
|
||||||
|
for i := 0 to size-2 do
|
||||||
|
for j := i+1 to size-1 do
|
||||||
|
if s[i].num < s[j].num then
|
||||||
|
begin
|
||||||
|
tmp := s[i];
|
||||||
|
s[i] := s[j];
|
||||||
|
s[j] := tmp;
|
||||||
|
end;
|
||||||
|
end; { sortArray }
|
||||||
|
|
||||||
|
procedure write_frequencies(fl : integer; buffer : PChar; buflen : longint);
|
||||||
|
var
|
||||||
|
ht : ht_pht;
|
||||||
|
i, size : longint;
|
||||||
|
total : real;
|
||||||
|
nd : ht_pnode;
|
||||||
|
s : sorterArray;
|
||||||
|
begin
|
||||||
|
ht := generate_frequencies(fl, buffer, buflen);
|
||||||
|
total := 0;
|
||||||
|
size := 0;
|
||||||
|
nd := ht_first(ht);
|
||||||
|
while (nd <> nil) do
|
||||||
|
begin
|
||||||
|
total := total + nd^.val;
|
||||||
|
size := size + 1;
|
||||||
|
nd := ht_next(ht);
|
||||||
|
end;
|
||||||
|
SetLength(s, size);
|
||||||
|
|
||||||
|
nd := ht_first(ht);
|
||||||
|
size := 0;
|
||||||
|
while (nd <> nil) do
|
||||||
|
begin
|
||||||
|
s[size].sequence := nd^.key;
|
||||||
|
strupper(s[size].sequence);
|
||||||
|
s[size].num := nd^.val;
|
||||||
|
size := size + 1;
|
||||||
|
nd := ht_next(ht);
|
||||||
|
end;
|
||||||
|
|
||||||
|
sortArray(s, size);
|
||||||
|
for i := 0 to size - 1 do
|
||||||
|
writeln(s[i].sequence,' ', (100 * s[i].num / total):3:3);
|
||||||
|
writeln;
|
||||||
|
|
||||||
|
ht_destroy(ht);
|
||||||
|
end; { write_frequencies }
|
||||||
|
|
||||||
|
procedure write_count(searchFor : PChar; buffer : PChar; buflen : longint);
|
||||||
|
var
|
||||||
|
ht : ht_pht;
|
||||||
|
nd : ht_pnode;
|
||||||
|
begin
|
||||||
|
ht := generate_frequencies (strlen (searchFor), buffer, buflen);
|
||||||
|
nd := ht_find(ht, searchFor);
|
||||||
|
if (nd <> nil) then
|
||||||
|
write(nd^.val)
|
||||||
|
else
|
||||||
|
write(0);
|
||||||
|
strupper(searchFor);
|
||||||
|
writeln(#9, searchFor);
|
||||||
|
|
||||||
|
ht_destroy(ht);
|
||||||
|
end; { write_count }
|
||||||
|
|
||||||
|
procedure main;
|
||||||
|
var
|
||||||
|
buffer : PChar;
|
||||||
|
len, seqlen : longint;
|
||||||
|
buffersize, bufferptr: longint;
|
||||||
|
s : String;
|
||||||
|
begin
|
||||||
|
seqlen := 0;
|
||||||
|
repeat
|
||||||
|
readln(s)
|
||||||
|
until (s[1] = '>') and (s[2] = 'T') and (s[3] = 'H');
|
||||||
|
buffersize:=1024;
|
||||||
|
buffer:=getmem(buffersize);
|
||||||
|
bufferptr :=0;
|
||||||
|
while not eof do begin
|
||||||
|
readln(s);
|
||||||
|
if (s[1] <> '>') and (s[1] <> ';') then begin
|
||||||
|
len:=length(s);
|
||||||
|
if (bufferptr+len+1)>buffersize then begin
|
||||||
|
inc(buffersize,buffersize);
|
||||||
|
reallocmem(buffer,buffersize);
|
||||||
|
end;
|
||||||
|
move (s[1],buffer[bufferptr],len);
|
||||||
|
inc(bufferptr,len);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
buffer[bufferptr] := #0;
|
||||||
|
seqlen := strlen(buffer);
|
||||||
|
|
||||||
|
write_frequencies(1, buffer, seqlen);
|
||||||
|
write_frequencies(2, buffer, seqlen);
|
||||||
|
write_count('ggt', buffer, seqlen);
|
||||||
|
write_count('ggta', buffer, seqlen);
|
||||||
|
write_count('ggtatt', buffer, seqlen);
|
||||||
|
write_count('ggtattttaatt', buffer, seqlen);
|
||||||
|
write_count('ggtattttaatttatagt', buffer, seqlen);
|
||||||
|
freemem(buffer);
|
||||||
|
end; { main }
|
||||||
|
|
||||||
|
|
||||||
|
begin
|
||||||
|
SetPrecisionMode(pmDouble);
|
||||||
|
main;
|
||||||
|
end.
|
260
tests/bench/shootout/src/simple_hash.pp
Normal file
260
tests/bench/shootout/src/simple_hash.pp
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
{
|
||||||
|
Copyright 2005, Micha Nelissen, converted from C, originally from
|
||||||
|
"simple_hash.h":
|
||||||
|
}
|
||||||
|
|
||||||
|
unit simple_hash;
|
||||||
|
|
||||||
|
{$mode objfpc}
|
||||||
|
{$inline on}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
const
|
||||||
|
ht_num_primes = 28;
|
||||||
|
|
||||||
|
ht_prime_list: array[0 .. ht_num_primes-1] of dword =
|
||||||
|
( 53, 97, 193, 389, 769,
|
||||||
|
1543, 3079, 6151, 12289, 24593,
|
||||||
|
49157, 98317, 196613, 393241, 786433,
|
||||||
|
1572869, 3145739, 6291469, 12582917, 25165843,
|
||||||
|
50331653, 100663319, 201326611, 402653189, 805306457,
|
||||||
|
1610612741, 3221225473, 4294967291 );
|
||||||
|
|
||||||
|
type
|
||||||
|
ht_ppnode = ^ht_pnode;
|
||||||
|
ht_pnode = ^ht_node;
|
||||||
|
ht_node = record
|
||||||
|
key: pchar;
|
||||||
|
val: integer;
|
||||||
|
next: ht_pnode;
|
||||||
|
end;
|
||||||
|
|
||||||
|
ht_pht = ^ht_ht;
|
||||||
|
ht_ht = record
|
||||||
|
size: dword;
|
||||||
|
tbl: ht_ppnode;
|
||||||
|
iter_index: dword;
|
||||||
|
iter_next: ht_pnode;
|
||||||
|
items: integer;
|
||||||
|
{$ifdef HT_DEBUG}
|
||||||
|
collisions: integer;
|
||||||
|
{$endif}
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ht_val(node: ht_pnode): integer; {inline;}
|
||||||
|
function ht_key(node: ht_pnode): pchar; {inline;}
|
||||||
|
function ht_hashcode(ht: ht_pht; key: pchar): integer; {inline;}
|
||||||
|
function ht_node_create(key: pchar): ht_pnode;
|
||||||
|
function ht_create(size: dword): ht_pht;
|
||||||
|
procedure ht_destroy(ht: ht_pht);
|
||||||
|
function ht_find(ht: ht_pht; key: pchar): ht_pnode; {inline;}
|
||||||
|
function ht_find_new(ht: ht_pht; key: pchar): ht_pnode; {inline;}
|
||||||
|
function ht_next(ht: ht_pht): ht_pnode; {inline;}
|
||||||
|
function ht_first(ht: ht_pht): ht_pnode; {inline;}
|
||||||
|
function ht_count(ht: ht_pht): integer; {inline;}
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
strings;
|
||||||
|
|
||||||
|
function ht_val(node: ht_pnode): integer; {inline;}
|
||||||
|
begin
|
||||||
|
result := node^.val;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ht_key(node: ht_pnode): pchar; {inline;}
|
||||||
|
begin
|
||||||
|
result := node^.key;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ht_hashcode(ht: ht_pht; key: pchar): integer; {inline;}
|
||||||
|
var
|
||||||
|
val: dword;
|
||||||
|
begin
|
||||||
|
val := 0;
|
||||||
|
while key^ <> #0 do
|
||||||
|
begin
|
||||||
|
val := 5 * val + byte(key^);
|
||||||
|
inc(key);
|
||||||
|
end;
|
||||||
|
result := val mod ht^.size;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ht_node_create(key: pchar): ht_pnode;
|
||||||
|
var
|
||||||
|
newkey: pchar;
|
||||||
|
node: ht_pnode;
|
||||||
|
begin
|
||||||
|
new(node);
|
||||||
|
newkey := strnew(key);
|
||||||
|
with node^ do
|
||||||
|
begin
|
||||||
|
key := newkey;
|
||||||
|
val := 0;
|
||||||
|
next := nil;
|
||||||
|
end;
|
||||||
|
result := node;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ht_create(size: dword): ht_pht;
|
||||||
|
var
|
||||||
|
i: integer;
|
||||||
|
ht: ht_pht;
|
||||||
|
begin
|
||||||
|
i := 0;
|
||||||
|
new(ht);
|
||||||
|
while ht_prime_list[i] < size do inc(i);
|
||||||
|
ht^.size := ht_prime_list[i];
|
||||||
|
ht^.tbl := allocmem(sizeof(ht_pnode) * ht^.size);
|
||||||
|
ht^.iter_index := 0;
|
||||||
|
ht^.iter_next := nil;
|
||||||
|
ht^.items := 0;
|
||||||
|
{$ifdef HT_DEBUG}
|
||||||
|
ht^.collisions := 0;
|
||||||
|
{$endif}
|
||||||
|
result := ht;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure ht_destroy(ht: ht_pht);
|
||||||
|
var
|
||||||
|
cur, next: ht_pnode;
|
||||||
|
i: integer;
|
||||||
|
{$ifdef HT_DEBUG}
|
||||||
|
chain_len, max_chain_len, density: integer;
|
||||||
|
{$endif}
|
||||||
|
begin
|
||||||
|
{$ifdef HT_DEBUG}
|
||||||
|
max_chain_len := 0;
|
||||||
|
density := 0;
|
||||||
|
writeln(' HT: size ', ht^.size);
|
||||||
|
writeln(' HT: items ', ht^.items);
|
||||||
|
writeln(' HT: collisions ', ht^.collisions);
|
||||||
|
{$endif}
|
||||||
|
for i := 0 to ht^.size-1 do
|
||||||
|
begin
|
||||||
|
next := ht^.tbl[i];
|
||||||
|
{$ifdef HT_DEBUG}
|
||||||
|
if next <> nil then
|
||||||
|
inc(density);
|
||||||
|
chain_len := 0;
|
||||||
|
{$endif}
|
||||||
|
while next <> nil do
|
||||||
|
begin
|
||||||
|
cur := next;
|
||||||
|
next := next^.next;
|
||||||
|
strdispose(cur^.key);
|
||||||
|
dispose(cur);
|
||||||
|
{$ifdef HT_DEBUG}
|
||||||
|
inc(chain_len);
|
||||||
|
{$endif}
|
||||||
|
end;
|
||||||
|
{$ifdef HT_DEBUG}
|
||||||
|
if chain_len > max_chain_len then
|
||||||
|
max_chain_len := chain_len;
|
||||||
|
{$endif}
|
||||||
|
end;
|
||||||
|
freemem(ht^.tbl);
|
||||||
|
dispose(ht);
|
||||||
|
{$ifdef HT_DEBUG}
|
||||||
|
writeln(' HT: density ', density);
|
||||||
|
writeln(' HT: max chain len ', max_chain_len);
|
||||||
|
{$endif}
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ht_find(ht: ht_pht; key: pchar): ht_pnode; {inline;}
|
||||||
|
var
|
||||||
|
hash_code: integer;
|
||||||
|
node: ht_pnode;
|
||||||
|
begin
|
||||||
|
hash_code := ht_hashcode(ht, key);
|
||||||
|
node := ht^.tbl[hash_code];
|
||||||
|
while node <> nil do
|
||||||
|
begin
|
||||||
|
if strcomp(key, node^.key) = 0 then
|
||||||
|
begin
|
||||||
|
result := node;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
node := node^.next;
|
||||||
|
end;
|
||||||
|
result := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ht_find_new(ht: ht_pht; key: pchar): ht_pnode; {inline;}
|
||||||
|
var
|
||||||
|
hash_code: integer;
|
||||||
|
prev, node: ht_pnode;
|
||||||
|
begin
|
||||||
|
hash_code := ht_hashcode(ht, key);
|
||||||
|
prev := nil;
|
||||||
|
node := ht^.tbl[hash_code];
|
||||||
|
while node <> nil do
|
||||||
|
begin
|
||||||
|
if strcomp(key, node^.key) = 0 then
|
||||||
|
begin
|
||||||
|
result := node;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
prev := node;
|
||||||
|
node := node^.next;
|
||||||
|
{$ifdef HT_DEBUG}
|
||||||
|
inc(ht^.collisions);
|
||||||
|
{$endif}
|
||||||
|
end;
|
||||||
|
inc(ht^.items);
|
||||||
|
result := ht_node_create(key);
|
||||||
|
if prev <> nil then
|
||||||
|
begin
|
||||||
|
prev^.next := result;
|
||||||
|
end else begin
|
||||||
|
ht^.tbl[hash_code] := result;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{
|
||||||
|
Hash Table iterator data / functions
|
||||||
|
}
|
||||||
|
|
||||||
|
function ht_next(ht: ht_pht): ht_pnode; {inline;}
|
||||||
|
var
|
||||||
|
index: dword;
|
||||||
|
node: ht_pnode;
|
||||||
|
begin
|
||||||
|
node := ht^.iter_next;
|
||||||
|
if node <> nil then
|
||||||
|
begin
|
||||||
|
ht^.iter_next := node^.next;
|
||||||
|
result := node;
|
||||||
|
exit;
|
||||||
|
end else begin
|
||||||
|
while ht^.iter_index < ht^.size do
|
||||||
|
begin
|
||||||
|
index := ht^.iter_index;
|
||||||
|
inc(ht^.iter_index);
|
||||||
|
if ht^.tbl[index] <> nil then
|
||||||
|
begin
|
||||||
|
ht^.iter_next := ht^.tbl[index]^.next;
|
||||||
|
result := ht^.tbl[index];
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
result := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ht_first(ht: ht_pht): ht_pnode; {inline;}
|
||||||
|
begin
|
||||||
|
ht^.iter_index := 0;
|
||||||
|
ht^.iter_next := nil;
|
||||||
|
result := ht_next(ht);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ht_count(ht: ht_pht): integer; {inline;}
|
||||||
|
begin
|
||||||
|
result := ht^.items;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user