Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Przyśpieszenie wywołania funkcji
Forum PHP.pl > Forum > PHP
kask18
Witam. Mam fragment kodu w którym dana funkcja w w pętli for nawet do 7 000 razy. Moje pytanie brzmi czy można jakoś przyspieszyć wywoływanie tej funkcji. Można by zrezygnować z samej funkcji i wkleić kod w for ale to rozwiązanie nie wchodzi w grę. Czy istnieje coś takiego jak w funkcja inline w C++ questionmark.gif Z góry dzięki za odpowiedzi.
wookieb
Jak napiszesz biblioteke do php-a to czemu nie. Prostszego sposobu nie ma. A co to za funkcja?
kask18
Mam funkcje która przyjmuje 2 argumenty stringi. Na podstawie tych strinów pobieram z bazy danych kilka tyś rekordów które filtruje napisanymi przeze mnie algorytmami. A następnie 'prawidłowych ' rekordów zwracam w postaci tablicy. Te czynności wyżej opisane wykonuje nawet do 7 000 ciągiem. wiec zależy mi żeby to jakoś przyspieszyć. Na mocnym serwerze operacje te nawet wykonują się przez 10 min. Algorytmy nie jestem już w stanie przyśpieszyć wiec szukam innych rozwiązań. W ciele tej funkcji wywołuje także inne funkcje wiec całość. Jest naprawdę obciązona
wookieb
Nawet gdyby ten kod nie był w funkcji a w ciele pętli to ogromnego wzrostu wydajności się nie spodziewaj. 1s nawet nie zyskasz.
Musiałbyś raczej pokazać co to za algorytm.
Sprawdzić:
1) Czy zapytania wywołują się odpowiednio szybko
2) Upewnić się czy NA PEWNO nie możesz usprawnić algorytmu
3) Czy optymalnie zaprojektowałeś bazę

Jeżeli będziesz podawał kod funkcji lub opisywał algorytm tutaj na forum to zrób to dokładnie, żebyśmy nie musieli pisać tysiąca postów aby "rozgryźć" co chcesz uzyskać.
krowal
To nie funkcja jest tutaj problemem ale ilość zapytań do bazy, nie robi się zapytań do bazy w pętli... a już na pewno nie takiej która się wykonuje 7k razy smile.gif Nie wiem dokładnie jak działa Twoja funkcja, ale podejrzewam, że można to załatwić mniejszą ilością zapytań. W tej pętli możesz zamiast zapytań np zrobić sobie listę id rekordów z którymi chcesz coś zrobić (w takiej postaci: "12, 42, 53, 65") A później zrobić jedno zapytanie poza pętlą: 'SELECT xxx FROM xxx WHERE id IN ($lista_id)'. Rozwiązań jest wiele, ale nikt Ci nie udzieli jednoznacznej odpowiedzi jak nie wkleisz kodu.
pozdr.
kask18
No więc tak mam tabele detal której dane należy przetworzyć i wyniki zachować w innej tabeli. Tabela detal zawiera pola tytuł i artysta. Są to atrybuty typu VARCHAR. Detal wchodzi w skład listy. Detali w liście może być nawet do 7 000. Pobieram wszystkie detale danej listy (po kluczu obcym). A następnie wykonuje w for przetworzenie kolejnych detali. Przetworzenie polega na porównaniu każdego detalu (pola tabeli tytuł artysa) z tabelą zawierającą bazowe nagrania. Pola tytuł artysta mają być porównywane bez uwzględniania polskich znaków oraz ich wielkości. Pola są porównywane za pomocą metody n-gramów. W tym wypadku jest to trigram. Cały ciąg jest rozbijany na 3-literowe ciągi które trzeba porównać z rekordami w tabeli bazowej nagrań. Zawęziłem pole przeszukiwań do ciągów o zbliżonej długości znaków. Założeniem funkcji jest określenie procentowego podobieństwa detalu do nagrania bazowego. Jeśli przekroczy ono pewny próg nagrnie zostaje to tablicy która następnie jest zwracana z funkcji.

Funkcja usuwająca polskie znaki:
  1. function usuwanie_polskich_znakow($str)
  2. {
  3. $polskie_znaki = array('ą','ć','ę','ł','ń','ó','ś','ź','ż', 'Ą','Ć','Ę','Ł','Ń','Ó','Ś','Ż','Ź',);
  4. $znaki = array('a','c','e','l','n','o','s','z','z', 'A','C','E','L','N','O','S','Z','Z');
  5. $str = str_replace($polskie_znaki, $znaki, $str);
  6.  
  7. return $str;
  8. }


Funkcja dzieląca ciąg na trójki
  1.  
  2. function tworz_trigram($str)
  3. {
  4. $dlugosc_str = strlen($str);
  5. $t_trigram = array();
  6. for($i=0; $i < ($dlugosc_str-2); $i++)
  7. $t_trigram[$i] = $str[$i].$str[$i+1].$str[$i+2];
  8.  
  9. return $t_trigram;
  10. }


Funkcja stannowiąca wąskie gardło (część 1):
  1. function trigram_imp($DBLink, $artysta_import, $tytul_import, $baza, $prog)
  2. {
  3. $podobienstwo = 0.00;
  4. $t_trigram_porownywany = array();
  5. $t_trigram_wzor = array();
  6. $znalezione_rekordy = array();
  7. $flag = true;
  8.  
  9. $artysta_import = usuwanie_polskich_znakow($artysta_import);
  10. $tytul_import = usuwanie_polskich_znakow($tytul_import);
  11. $artysta_import = strtolower(trim(stripslashes($artysta_import)));
  12. $tytul_import = strtolower(trim(stripslashes($tytul_import)));
  13.  
  14. //--------------------------------------------------
  15. $min_z = strlen($tytul_import)-2;
  16. if($min_z <=0)$min_z = 1;
  17. $max_z = strlen($tytul_import) + 3;
  18.  
  19. //--------------------------------------------------
  20. $min_z2 = strlen($artysta_import)-2;
  21. if($min_z2 <=0)$min_z2 = 1;
  22. $max_z2 = strlen($artysta_import) + 3;
  23.  
  24. $select_wzor = "SELECT * FROM baza_trackow WHERE id_track_zmieniony IS NULL
  25. AND char_length(tytul) >=".$min_z." AND char_length(tytul) <= ".$max_z.
  26. " AND char_length(artysta) >=".$min_z2." AND char_length(artysta) <= ".$max_z2;
  27.  
  28. $t_wynik_zapytania = $DBLink->query($select_wzor);
  29. $ilosc_rekordow_baza = $t_wynik_zapytania->num_rows;
  30.  
  31.  
  32. $progi_procentowe = "SELECT wartosc FROM konfiguracje
  33. WHERE ustawienie = 'prog_b' OR ustawienie = 'prog_c' ORDER BY ustawienie ";
  34. $t_progi_procentowe = $DBLink->query($progi_procentowe);
  35.  
  36. $artysta_import = ' '.$artysta_import.' ';
  37. $tytul_import = ' '.$tytul_import.' ';
  38.  
  39. $t_trigram_artysta_import = tworz_trigram($artysta_import);
  40. $t_trigram_tytul_import = tworz_trigram($tytul_import);
  41.  


czesc 2:

  1. // pętla porównująca wyniki z bazy z porówywanym nagraniem na playliscie
  2. for($i=0; $i < $ilosc_rekordow_baza; $i++)
  3. {
  4. $rekord = $t_wynik_zapytania ->fetch_assoc();
  5.  
  6. $str_wzor_artysta = usuwanie_polskich_znakow($rekord['artysta']);
  7. $str_wzor_tytul = usuwanie_polskich_znakow($rekord['tytul']);
  8. $str_wzor_artysta = strtolower(trim(stripslashes($str_wzor_artysta)));
  9. $str_wzor_tytul = strtolower(trim(stripslashes($str_wzor_tytul)));
  10.  
  11. $str_wzor_artysta = ' '.$str_wzor_artysta.' ';
  12. $str_wzor_tytul = ' '.$str_wzor_tytul.' ';
  13.  
  14. //artysta
  15. $strlen_str_porownywany = strlen($artysta_import);
  16. $strlen_str_wzor = strlen($str_wzor_artysta);
  17.  
  18. // podzial stringu pobranego z bazy na trigramy
  19. $t_trigram_wzor = tworz_trigram($str_wzor_artysta);
  20. $t_trigram_porownywany = $t_trigram_artysta_import;
  21.  
  22.  
  23. if($strlen_str_porownywany >= $strlen_str_wzor)
  24. {
  25. $ilosc_kombinacji = count($t_trigram_porownywany);
  26. $procent = (1 / $ilosc_kombinacji) * 100;
  27. $ilosc_kombinacji = count($t_trigram_wzor);
  28. }
  29.  
  30. else if($strlen_str_porownywany < $strlen_str_wzor)
  31. {
  32. $ilosc_kombinacji_wzor = count($t_trigram_wzor);
  33. $procent = (1 / $ilosc_kombinacji_wzor) * 100;
  34. $ilosc_kombinacji = count($t_trigram_porownywany);
  35. }
  36. $podobienstwo = 0;
  37. for($j=0; $j < $ilosc_kombinacji; $j++)
  38. {
  39. if($t_trigram_wzor[$j] == $t_trigram_porownywany[$j]){ $podobienstwo += $procent;}
  40. }
  41. $podobienstwoA = $podobienstwo;
  42.  
  43. $podobienstwo = 0;
  44.  
  45.  
  46. //----------------------------------------------------------------------------------------
  47. //----------------------------------------------- tytul ----------------------------------
  48.  


czesc 3:

  1.  
  2. $strlen_str_porownywany = strlen($tytul_import);
  3. $strlen_str_wzor = strlen($str_wzor_tytul);
  4.  
  5. // podzial stringu pobranego z bazy na trigramy
  6. $t_trigram_wzor = tworz_trigram($str_wzor_tytul);
  7. $t_trigram_porownywany = $t_trigram_tytul_import;
  8.  
  9. if($strlen_str_porownywany >= $strlen_str_wzor)
  10. {
  11. $ilosc_kombinacji = count($t_trigram_porownywany);
  12. $procent = (1 / $ilosc_kombinacji) * 100;
  13. $ilosc_kombinacji = count($t_trigram_wzor);
  14.  
  15. }
  16.  
  17. else if($strlen_str_porownywany < $strlen_str_wzor)
  18. {
  19. $ilosc_kombinacji_wzor = count($t_trigram_wzor);
  20. $procent = (1 / $ilosc_kombinacji_wzor) * 100;
  21. $ilosc_kombinacji = count($t_trigram_porownywany);
  22. }
  23.  
  24. for($j=0; $j < $ilosc_kombinacji; $j++)
  25. {
  26. if($t_trigram_wzor[$j] == $t_trigram_porownywany[$j]){ $podobienstwo += $procent;}
  27. }
  28.  
  29. $podobienstwoB = $podobienstwo;
  30.  
  31. $podobienstwo = 0;
  32.  
  33.  
  34. // Zwraca rekordy zgrupowane kÄ,Ĺ,trych prÄ,Ĺ,g podobiensta przekroczyl A
  35. // Jesli brak takich nagran to nic nie jest zwracane
  36.  
  37. $podobienstwo = ($podobienstwoA/2) + ($podobienstwoB/2);
  38.  
  39. if($podobienstwo >= $prog['prog_b'])
  40. {
  41. $rekord['podobienstwo'] = 'A';
  42. $rekord['procent'] = number_format($podobienstwo,2);
  43. if($flag)$znalezione_rekordy = Array();
  44. $znalezione_rekordy[count($znalezione_rekordy)+1] = $rekord;
  45. $flag = false;
  46. }
  47. else if($podobienstwo < $prog['prog_b'] && $podobienstwo >= $prog['prog_c'] && $flag = true)
  48. {
  49. $rekord['podobienstwo'] = 'B';
  50. $rekord['procent'] = number_format($podobienstwo,2);
  51. $znalezione_rekordy[count($znalezione_rekordy)+1] = $rekord;
  52. }
  53.  
  54.  
  55.  
  56. }
  57.  
  58. return $znalezione_rekordy;
  59. }
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.