Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Benchmark w PHP, benchmark, ale nie profiler
q.michal
post 15.06.2017, 21:12:27
Post #1





Grupa: Zarejestrowani
Postów: 111
Pomógł: 1
Dołączył: 24.12.2013

Ostrzeżenie: (0%)
-----


Hello,

Dzis przedstawiam na szybko napisane 3 metody do testowania wydajnosci CPU, operacji I/O oraz bazy danych.
Kazda metoda zwraca przyznane punkty w formie INTa. Oczywiscie im wiecej tym lepiej.

Uwagi odnosnie tej jakze nikomu niepotrzebnej klasie jak zwykle mile widziane Lkingsmiley.png

Klasa:
  1. <?php
  2.  
  3. final class Benchmark {
  4.  
  5. /**
  6. * Benchmarks CPU and returns performance score
  7. *
  8. * @return integer CPU performance score
  9. */
  10. public static function getCPUScore() {
  11. $k = 0;
  12. $result = [];
  13. for($i = 0; $i < 25; $i++) {
  14. $start = System::getMiroTime();
  15. for($j = 0; $j < 1000000; $j++) {
  16. }
  17. $loop1 = System::getMiroTime() - $start;
  18. $start = System::getMiroTime();
  19. for($j = 0; $j < 1000000; $j++) {
  20. $k++;
  21. $k--;
  22. $k++;
  23. $k--;
  24. }
  25. $loop2 = System::getMiroTime() - $start;
  26. if ($loop2 > $loop1)
  27. $result[] = 1 / ($loop2 - $loop1);
  28. }
  29. if(count($result)) {
  30. return (int) round(array_sum($result) / doubleval(count($result)));
  31. } else {
  32. return 0;
  33. }
  34. }
  35.  
  36. /**
  37. * Benchmarks database and returns performance score
  38. *
  39. * @param object database object
  40. * @return integer database operations score
  41. * @throws exception if database connection or SQL query fails
  42. */
  43. public static function getDatabaseScore($database) {
  44. if(!is_a($database, 'Platform\\Database') || !$database->isConnected()) {
  45. throw new \Exception('No connection to database');
  46. }
  47. try {
  48. $database->setQuery('DELETE FROM #__performance');
  49. $database->execute();
  50. } catch(\PDOException $e) {
  51. throw new \Exception('Unable to truncate #__performance table');
  52. }
  53. $result = [];
  54. for($i = 0; $i < 25; $i++) {
  55. $start = System::getMiroTime();
  56. for($j = 0; $j < 10; $j++) {
  57. str_repeat('xyz', 66);
  58. }
  59. $loop1 = System::getMiroTime() - $start;
  60. $start = System::getMiroTime();
  61. for($j = 0; $j < 10; $j++) {
  62. try {
  63. $database->setQuery('INSERT INTO #__performance(ID, REF_ID, NAME) VALUES (?, ?, ?)');
  64. $database->execute([NULL, $j, str_repeat('xyz', 66)]);
  65. $database->setQuery('SELECT * FROM #__performance WHERE REF_ID = ?');
  66. $database->execute([$j]);
  67. $database->fetchRow();
  68. } catch(\PDOException $e) {
  69. throw new \Exception('Query execution failed during database benchmark');
  70. }
  71. }
  72. $loop2 = System::getMiroTime() - $start;
  73. if($loop2 > $loop1) {
  74. $result[] = 100 / ($loop2 - $loop1);
  75. }
  76. }
  77. if(count($result)) {
  78. return (int) round(array_sum($result) / doubleval(count($result)));
  79. } else {
  80. return 0;
  81. }
  82. }
  83.  
  84. /**
  85. * Benchmarks I/O operations and returns performance score
  86. *
  87. * @param string path to directory where temporary files necessary for test will be created
  88. * @return integer I/O operations performance score
  89. */
  90. public static function getIOScore($tempdir = '.') {
  91. $result = [];
  92. $testfile = $tempdir . '/io_benchmark_#N#.dat';
  93. $content = '<?php /*' . str_repeat('I/O Benchmark. ', 1024) . '*/ ?>';
  94. for($i = 0; $i < 25; $i++) {
  95. $start = System::getMiroTime();
  96. for($j = 0; $j < 1000; $j++) {
  97. str_replace("#N#", $j, $testfile);
  98. }
  99. $loop1 = System::getMiroTime() - $start;
  100. $start = System::getMiroTime();
  101. for($j = 0; $j < 1000; $j++) {
  102. $file = str_replace("#N#", $j, $testfile);
  103. file_put_contents($file, $content, LOCK_EX);
  104. require($file);
  105. unlink($file);
  106. }
  107. $loop2 = System::getMiroTime() - $start;
  108. if($loop2 > $loop1)
  109. $result[] = 1000 / ($loop2 - $loop1);
  110. }
  111. if(count($result)) {
  112. return (int) round(array_sum($result) / doubleval(count($result)));
  113. } else {
  114. return 0;
  115. }
  116. }
  117.  
  118. } /* class */


Przyklad uzycia:
  1. <?php
  2.  
  3. try {
  4. $database = \Platform\Database::getInstance();
  5. $database->connect('sqlite:tests/data/database.qdb', NULL, NULL, 'test_');
  6. $database->setQuery('CREATE TABLE IF NOT EXISTS #__performance(`ID` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, `REF_ID` INTEGER DEFAULT NULL, `NAME` varchar(200) DEFAULT NULL)');
  7. $database->execute();
  8. }
  9. catch(\PDOException $e) {
  10. die('Something went wrong!');
  11. }
  12.  
  13. var_dump(\Platform\Benchmark::getCPUScore());
  14. var_dump(\Platform\Benchmark::getDatabaseScore($database));
  15. var_dump(\Platform\Benchmark::getIOScore('.'));


Wyniki:
Kod
int(187)
int(153)
int(1224)


Ten post edytował q.michal 16.06.2017, 15:04:39
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
q.michal
post 16.06.2017, 12:25:38
Post #2





Grupa: Zarejestrowani
Postów: 111
Pomógł: 1
Dołączył: 24.12.2013

Ostrzeżenie: (0%)
-----


Tak, wiem wink.gif
Skupilem sie wylacznie na funkcjonalnosci i jak napisalem w 1 poscie, jest to kod napisany na szybko.
Moze ktos znajdzie dla niego zastosowanie / natchnienie we wlasnym projekcie.


edit: Zauwazylem 'drobna literowke'. Drobna, bo zjadlem zero, a zmienia diametralnie wynik.
W linii 109 bylo:
$result[] = 100 / ($loop2 - $loop1);

a powinno byc:
$result[] = 1000 / ($loop2 - $loop1);

Ten post edytował q.michal 16.06.2017, 15:04:22
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 18.04.2024 - 06:46