Benchmark hašovacích tabuliek v PHP cez jednoduchú key-value databázu
Podmienky testovania
upraviť- programovací jazyk PHP 7.3.27-1~deb10u1
- testovacia aplikácia bola „jednovláknová“
- dáta typu sú interné ukladané ako hašovacie tabuľky[1]
- implementovaná jednoduchá key-value databáza
- databáza je uložená celá v pamäte RAM
- hodnoty key je snaha ukladať ako reťazce resp. blok pamäte
- hodnoty value sú generované náhodne
- import nových dát prebieha z vopred vygenerovaného CSV
- export nových dát prebieha do CSV
- priamy export do CSV bez konverzií (očakáva, že vstupné dáta sú iba: 'a' – 'z', 'A' – 'Z' a '0' – '9')
Názvy testov
upraviťNázov je podľa číselných hodnôt konštánt v zdrojovom kóde:
KEY_LENGTH – VALUES – VALUE_LENGTH
Význam konštánt:
- KEY_LENGTH – koľko bajtov budeme používať pre ukladanie kľúča
- VALUES – koľko hodnôt sa bude ukladanie pri key-value databáze
- 1 – napr. pre číslo položky, adresu alebo 1 informáciu
- 2 – napr. pre ofsety začiatok-koniec
- VALUE_LENGTH – veľkosť value v bajtov
Výsledky testovania
upraviťTesty | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
4 – 1 – 4 | 4 – 2 – 4 | 8 – 1 – 4 | 8 – 2 – 4 | |||||||||
záznamov po pridaní [milióny] | čas importu [s] | čas exportu [s] | použitá pamäť [MB] | čas importu [s] | čas exportu [s] | použitá pamäť [MB] | čas importu [s] | čas exportu [s] | použitá pamäť [MB] | čas importu [s] | čas exportu [s] | použitá pamäť [MB] |
1 | 0,58 | 0,63 | 143 | 0,98 | 0,63 | 157 | 0,70 | 0,69 | 461 | 1,09 | 0,69 | 478 |
2 | 0,59 | 1,26 | 216 | 1,01 | 1,29 | 241 | 0,70 | 1,35 | 858 | 1,11 | 1,37 | 881 |
3 | 0,60 | 1,91 | 331 | 1,04 | 1,96 | 365 | 0,72 | 2,00 | 1294 | 1,12 | 2,05 | 1328 |
4 | 0,57 | 2,58 | 363 | 0,99 | 2,59 | 405 | 0,69 | 2,70 | 1646 | 1,07 | 2,74 | 1688 |
5 | 0,68 | 3,24 | 564 | 1,06 | 3,20 | 612 | 0,76 | 3,37 | 2166 | 1,19 | 3,44 | 2217 |
6 | 0,58 | 3,85 | 596 | 0,99 | 3,82 | 652 | 0,71 | 4,14 | 2519 | 1,09 | 4,09 | 2577 |
7 | 0,58 | 4,66 | 627 | 0,99 | 4,49 | 692 | 0,70 | 4,73 | 2873 | 1,13 | 4,91 | 2938 |
8 | 0,58 | 5,20 | 661 | 0,99 | 5,15 | 734 | 0,72 | 5,55 | 3225 | 1,13 | 5,54 | 3299 |
9 | 0,77 | 5,85 | 1028 | 1,18 | 5,82 | 1109 | 0,92 | 6,29 | 3913 | 1,33 | 6,14 | 3995 |
10 | 0,58 | 6,38 | 1059 | 0,98 | 6,39 | 1149 | 0,73 | 6,93 | 4266 | 1,13 | 6,72 | 4356 |
11 | 0,58 | 7,36 | 1091 | 0,99 | 7,17 | 1189 | 0,60 | 7,43 | 4297 | 0,99 | 7,44 | 4396 |
12 | 0,60 | 7,97 | 1124 | 1,00 | 7,84 | 1229 | 0,60 | 8,20 | 4329 | 1,01 | 8,20 | 4435 |
13 | 0,59 | 8,51 | 1156 | 0,99 | 8,42 | 1271 | 0,61 | 8,70 | 4362 | 0,99 | 8,80 | 4475 |
14 | 0,58 | 9,14 | 1187 | 1,00 | 9,00 | 1311 | 0,60 | 9,48 | 4394 | 1,00 | 9,52 | 4515 |
15 | 0,59 | 9,98 | 1221 | 0,99 | 9,56 | 1351 | 0,59 | 9,79 | 4425 | 1,00 | 10,04 | 4557 |
16 | 0,59 | 10,41 | 1252 | 1,00 | 10,26 | 1390 | 0,57 | 10,56 | 4459 | 1,00 | 10,84 | 4597 |
17 | 0,96 | 10,95 | 1955 | 1,38 | 10,86 | 2101 | 1,01 | 11,32 | 5161 | 1,40 | 11,45 | 5308 |
18 | 0,58 | 11,72 | 1986 | 0,97 | 11,51 | 2141 | 0,60 | 12,07 | 5193 | 1,01 | 12,36 | 5348 |
19 | 0,59 | 12,48 | 2020 | 0,98 | 12,04 | 2183 | 0,60 | 12,76 | 5224 | 1,00 | 12,87 | 5388 |
20 | 0,61 | 13,23 | 2051 | 1,00 | 12,90 | 2223 | 0,59 | 13,49 | 5258 | 0,98 | 13,47 | 5430 |
21 | 0,59 | 13,94 | 2082 | 0,98 | 13,33 | 2263 | 0,60 | 13,87 | 5289 | 0,99 | 14,03 | 5469 |
22 | 0,59 | 14,19 | 2116 | 0,98 | 14,00 | 2303 | 0,60 | 14,59 | 5320 | 0,99 | 14,53 | 5509 |
23 | 0,59 | 14,77 | 2147 | 0,99 | 14,70 | 2343 | 0,60 | 15,35 | 5354 | 0,99 | 15,16 | 5549 |
24 | 0,58 | 15,26 | 2179 | 1,00 | 15,34 | 2384 | 0,62 | 16,23 | 5385 | 1,01 | 16,12 | 5589 |
25 | 0,58 | 16,23 | 2210 | 0,97 | 16,10 | 2424 | 0,62 | 16,90 | 5417 | 1,02 | 16,81 | 5631 |
26 | 0,58 | 17,03 | 2244 | 0,99 | 16,60 | 2464 | 0,60 | 17,67 | 5448 | 1,02 | 17,24 | 5671 |
27 | 0,58 | 17,36 | 2275 | 0,97 | 17,05 | 2504 | 0,60 | 18,10 | 5482 | 1,00 | 18,13 | 5711 |
28 | 0,59 | 17,98 | 2307 | 0,97 | 17,65 | 2544 | 0,60 | 18,69 | 5513 | 0,98 | 18,71 | 5750 |
29 | 0,59 | 18,76 | 2340 | 1,01 | 18,62 | 2586 | 0,61 | 19,11 | 5545 | 0,99 | 19,52 | 5790 |
30 | 0,58 | 19,24 | 2372 | 1,01 | 19,44 | 2626 | 0,58 | 20,00 | 5578 | 1,02 | 20,04 | 5830 |
31 | 0,61 | 19,97 | 2403 | 1,00 | 19,93 | 2665 | 0,60 | 21,04 | 5610 | 1,00 | 20,50 | 5872 |
32 | 0,58 | 20,69 | 2435 | 0,98 | 20,59 | 2705 | 0,60 | 21,24 | 5641 | 1,00 | 21,38 | 5912 |
33 | 0,59 | 21,36 | 2468 | 0,97 | 21,23 | 2745 | 0,60 | 21,96 | 5673 | 1,02 | 22,15 | 5952 |
34 | 1,33 | 21,80 | 3842 | 1,76 | 22,11 | 4127 | 1,40 | 22,45 | 7049 | 1,77 | 22,93 | 7334 |
35 | 0,57 | 22,87 | 3873 | 0,99 | 22,73 | 4169 | 0,59 | 22,82 | 7080 | 1,02 | 23,48 | 7374 |
36 | 0,60 | 23,61 | 3907 | 0,99 | 23,31 | 4209 | 0,60 | 24,12 | 7111 | 1,01 | 24,04 | 7416 |
37 | 0,59 | 23,99 | 3938 | 0,99 | 23,98 | 4249 | 0,63 | 24,59 | 7145 | 0,99 | 24,60 | 7455 |
38 | 0,57 | 24,47 | 3970 | 0,98 | 24,57 | 4289 | 0,61 | 25,44 | 7176 | 1,02 | 24,75 | 7495 |
39 | 0,58 | 25,26 | 4003 | 0,98 | 24,97 | 4329 | 0,60 | 26,12 | 7208 | 0,99 | 26,00 | 7535 |
40 | 0,59 | 25,93 | 4035 | 0,98 | 25,89 | 4370 | 0,60 | 26,79 | 7241 | 0,98 | 26,45 | 7575 |
41 | 0,60 | 27,05 | 4066 | 0,98 | 26,42 | 4410 | 0,61 | 27,12 | 7273 | 1,00 | 26,98 | 7615 |
42 | 0,58 | 27,44 | 4098 | 1,01 | 27,19 | 4450 | 0,59 | 28,42 | 7304 | 1,02 | 27,63 | 7657 |
43 | 0,60 | 28,40 | 4131 | 1,00 | 28,06 | 4490 | 0,59 | 28,66 | 7336 | 0,99 | 28,52 | 7697 |
44 | 0,59 | 28,63 | 4163 | 1,01 | 27,95 | 4530 | 0,61 | 29,74 | 7369 | 1,03 | 29,01 | 7736 |
45 | 0,59 | 29,46 | 4194 | 0,98 | 28,86 | 4572 | 0,60 | 29,62 | 7401 | 1,00 | 29,66 | 7776 |
46 | 0,59 | 30,45 | 4228 | 1,00 | 29,91 | 4612 | 0,59 | 30,05 | 7432 | 1,02 | 30,31 | 7816 |
47 | 0,60 | 30,71 | 4259 | 0,99 | 30,55 | 4651 | 0,59 | 30,85 | 7466 | 0,99 | 31,53 | 7858 |
48 | 0,61 | 31,62 | 4291 | 0,98 | 31,19 | 4691 | 0,61 | 32,29 | 7497 | 0,99 | 31,95 | 7898 |
49 | 0,58 | 31,85 | 4322 | 0,99 | 32,07 | 4731 | 0,60 | 32,50 | 7529 | 1,03 | 32,22 | 7938 |
50 | 0,57 | 32,10 | 4356 | 0,99 | 32,64 | 4771 | 0,60 | 32,84 | 7560 | 1,02 | 33,32 | 7978 |
Zdrojový kód na testovanie
upraviť<?php
define("COUNT_IMPORT", -1);
define("RECORDS", 1000000);
define("KEY_LENGTH", 8);
define("VALUES", 2);
define("VALUE_LENGTH", 4); // 2, 4, 6, 8 and more – for generator
function render_csv()
{
$csv="";
$last_item_index=VALUES-1;
for($a=0;$a<RECORDS;$a++)
{
for($b=0;$b<VALUES;$b++)
{
$bytes=random_bytes(VALUE_LENGTH/2);
$item=bin2hex($bytes);
if($b == $last_item_index)
$csv.="$item\n";
else
$csv.="$item,";
}
}
return $csv;
}
$txt="count before | count added | count after | time of import (s) | time of export (s) | alloced memory\n";
echo "$txt\n";
file_put_contents("test.log", "$txt\n");
$date=array();
$new_key=0;
$step=0;
while(1)
{
$import=render_csv();
$count_before=count($date);
// import
$start_import=microtime(true);
$lines=explode("\n", $import);
unset($lines[count($lines)-1]);
foreach($lines as $line)
{
// key
$key=sprintf("%0".KEY_LENGTH."d", $new_key);
$new_key++;
// record
$values=str_getcsv($line);
$record_raw=implode("", $values);
// add to date
$date["$key"]=$record_raw;
}
$count_after=count($date);
$count_diff=$count_after-$count_before;
$end_import=microtime(true);
$diff_import=sprintf("%0.3f", $end_import-$start_import);
unset($import);
// export
$start_export=microtime(true);
$fd=fopen("/dev/null", "w");
if($fd === false)
exit;
foreach($date as $key => $value)
fwrite($fd, "$key,$value\n");
fclose($fd);
$end_export=microtime(true);
$diff_export=sprintf("%0.3f", $end_export-$start_export);
$usage_memory=memory_get_usage(true);
$txt="$count_before | $count_diff | $count_after | $diff_import | $diff_export | $usage_memory";
echo "$txt\n";
file_put_contents("test.log", "$txt\n", FILE_APPEND);
$step++;
if($step == COUNT_IMPORT)
{
echo "\n";
break;
}
}
Referencie
upraviť- ↑ COMPANY, Sudo Null. Arrays in PHP 7: Hash Tables [online]. sudonull.com, [cit. 2021-06-26]. Dostupné online.