Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Przyśpieszenie wywołania funkcji
kask18
post
Post #1





Grupa: Zarejestrowani
Postów: 121
Pomógł: 0
Dołączył: 3.12.2008

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


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++ (IMG:style_emoticons/default/questionmark.gif) Z góry dzięki za odpowiedzi.
Go to the top of the page
+Quote Post
wookieb
post
Post #2





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Jak napiszesz biblioteke do php-a to czemu nie. Prostszego sposobu nie ma. A co to za funkcja?
Go to the top of the page
+Quote Post
kask18
post
Post #3





Grupa: Zarejestrowani
Postów: 121
Pomógł: 0
Dołączył: 3.12.2008

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


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
Go to the top of the page
+Quote Post
wookieb
post
Post #4





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




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ć.
Go to the top of the page
+Quote Post
krowal
post
Post #5





Grupa: Zarejestrowani
Postów: 561
Pomógł: 72
Dołączył: 15.11.2006

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


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 (IMG:style_emoticons/default/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.
Go to the top of the page
+Quote Post
kask18
post
Post #6





Grupa: Zarejestrowani
Postów: 121
Pomógł: 0
Dołączył: 3.12.2008

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


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. }
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 23.08.2025 - 06:51