Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Optymalizacja kodu
Forum PHP.pl > Forum > PHP
nexis
Poniższy program importuje cennik zapisany w formacie XML i ważący obecnie 27 510 582 bajtów (ok. 26 MB) do bazy danych MySQL:

  1. <?php
  2. require 'mysql.php';
  3.  
  4. function utf2iso ($string) {
  5. $length = strlen($string);
  6. $output = '';
  7. $j = 0;
  8. for ($i=0; $i < $length; $i++) {
  9. if (ord($string[$i]) == 197) {
  10. switch (ord($string[$i+1])) {
  11. case 129:
  12. $output .= 'Ł';
  13. break;
  14. case 130:
  15. $output .= 'ł';
  16. break;
  17. case 155:
  18. $output .= 'ś';
  19. break;
  20. case 187:
  21. $output .= 'Ż';
  22. break;
  23. case 188:
  24. $output .= 'ż';
  25. break;
  26. }
  27. $i++;
  28. } else if (ord($string[$i]) == 195) {
  29. switch (ord($string[$i+1])) {
  30. case 179:
  31. $output .= 'ó';
  32. break;
  33. }
  34. $i++;
  35. } else if (ord($string[$i]) == 196) {
  36. switch (ord($string[$i+1])) {
  37. case 133:
  38. $output .= 'ą';
  39. break;
  40. case 153:
  41. $output .= 'ę';
  42. break;
  43. }
  44. $i++;
  45. } else if (ord($string[$i]) == 226 || ord($string[$i]) == 128 || ord($string[$i]) == 138) {
  46. $output .= '.';
  47. } else $output .= $string[$i];
  48. }
  49. return addslashes($output);
  50. }
  51.  
  52. mysql_query('TRUNCATE TABLE sklep_grupa') or die(mysql_error());
  53. mysql_query('TRUNCATE TABLE sklep_producent') or die(mysql_error());
  54. mysql_query('TRUNCATE TABLE sklep_produkt') or die(mysql_error());
  55. mysql_query('TRUNCATE TABLE sklep_zdjecie') or die(mysql_error());
  56. mysql_query('TRUNCATE TABLE sklep_parametr') or die(mysql_error());
  57.  
  58. $xml = new XMLReader();
  59. $xml->open('cennik.xml');
  60.  
  61. $super = '';
  62. $prod = '';
  63.  
  64. while ($xml->read())
  65. {
  66. switch ($xml->name)
  67. {
  68. case 'GrupaGlowna':
  69. mysql_query ("REPLACE INTO sklep_grupa VALUES ('" . $xml->getAttribute("id") . "', '', '" . utf2iso($xml->getAttribute("nazwa")) . "');") or die (mysql_error());
  70. $super = $xml->getAttribute("id");
  71. break;
  72. case 'PodGrupa':
  73. mysql_query ("REPLACE INTO sklep_grupa VALUES ('" . $xml->getAttribute("id") . "', '" . $super . "', '" . utf2iso($xml->getAttribute("nazwa")) . "');") or die (mysql_error());
  74. break;
  75. case 'producent':
  76. mysql_query ("REPLACE INTO sklep_producent VALUES ('" . $xml->getAttribute("id") . "', '" . htmlspecialchars(utf2iso($xml->getAttribute("nazwa"))) . "');") or die (mysql_error());
  77. break;
  78. case 'produkt':
  79. mysql_query ("REPLACE INTO sklep_produkt VALUES ('" . $xml->getAttribute("id") . "', '" . utf2iso($xml->getAttribute("nazwa")) . "', '" . $xml->getAttribute("producent") . "', '" . $xml->getAttribute("grupa") . "', '" . $xml->getAttribute("gwarancja") . "', '" . $xml->getAttribute("cena_netto") . "', '" . ($xml->getAttribute("cena_netto")*1.22) . "', '" . $xml->getAttribute("dostepny") . "', '" . $xml->getAttribute("data") . "');") or die (mysql_error());
  80. $prod = $xml->getAttribute("id");
  81. break;
  82. case 'zdjecie':
  83. mysql_query ("REPLACE INTO sklep_zdjecie VALUES ('$prod', '" . $xml->getAttribute("plik") . "', '" . $xml->getAttribute("domyslne") . "', '" . $xml->getAttribute("data") . "');") or die (mysql_error());
  84. break;
  85. case 'parametr':
  86. mysql_query ("REPLACE INTO sklep_parametr VALUES ('$prod', '" . utf2iso($xml->getAttribute("nazwa")) . "', '" . utf2iso($xml->getAttribute("opis")) . "', '" . $xml->getAttribute("jm") . "');") or die (mysql_error());
  87. break;
  88. default:
  89. }
  90. }
  91. ?>


Dodam, że funkcja utf2iso musi istnieć, ponieważ iconv" title="Zobacz w manualu PHP" target="_manual sobie nie radził z niektórymi znakami. Dodatkowo nie wiedząc czemu, rekordy wstawiały się dwukrotnie - stąd użycie odpowiednich kluczy w bazie danych i zapytania typu REPLACE.

Czy w powyższym kodzie można coś poprawić co ewentualnie zwiększyłoby jego wydajność (skróciło czas wykonania)? Obecnie wynosi on ok. 180 sekund!
Kocurro
Myślę, że użycie SAX'a sprawiłoby, że kod wykonywałby się szybciej. Ale to zejdzie Ci trochę na przepisanie pod SAX'a ... więc musisz sam policzyć czy ewentualny zysk jest tego wart czy też nie ...

Do tego proponowałbym inaczej napisać funkcję utf2iso.

A także pomyśleć nad użyciem prepared statements - jeśli masz je dostępne a jeśli nie to generować zapytania na bieżąco w callbackach sax'a.

I przede wszystkim przemyśl jeszcze raz użyty algorytm (skoro mówisz, że dublowały się wpisy to znaczy, że masz algorytm źle skonstruowany) - spróbuj zapisać go tak by duble nie miały prawa się pojawić.

Jeszcze na początek proponuję dołożenie kodu profilującego na bazie microtime by sprawdzić co najwięcej czasu zabiera - czy xml, czy baza czy php. I starać się przede wszystkim to zoptymalizować.
kukix
tak... popatrz dlaczego dodaje sie dwukrotnie... byc może zaoszczędzisz na tym nawet 30-40% czasu.. pozdr...

P.S. to nie jest przypadkiem cennik actiona smile.gif questionmark.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.