Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Optymalizacja kodu
nexis
post 17.11.2007, 00:52:34
Post #1





Grupa: Zarejestrowani
Postów: 1 012
Pomógł: 109
Dołączył: 26.09.2003
Skąd: nexis.pl

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


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!

Ten post edytował nexis 17.11.2007, 00:56:45


--------------------
Zend Certified Engineer

Kliknij POMÓGŁ jeśli moja odpowiedź okazała się użyteczna!
Go to the top of the page
+Quote Post
Kocurro
post 17.11.2007, 03:06:08
Post #2





Grupa: Zarejestrowani
Postów: 461
Pomógł: 32
Dołączył: 17.09.2003
Skąd: Łódź

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


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ć.

Ten post edytował Kocurro 17.11.2007, 03:09:29
Go to the top of the page
+Quote Post
kukix
post 15.02.2008, 19:32:34
Post #3





Grupa: Zarejestrowani
Postów: 600
Pomógł: 2
Dołączył: 1.09.2002
Skąd: Wrocław

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


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

Ten post edytował kukix 15.02.2008, 19:47:01
Go to the top of the page
+Quote Post

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: 24.07.2025 - 18:31