Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wydajność __autoload
Forum PHP.pl > Forum > PHP > Object-oriented programming
athabus
Zastanwiam się na użyciem __autoload w moim nowy projekcie. Wiem, że na php pro jest wątek na temat optymalizacji __autoload, ale mi zależy na prostym rozwiązaniu bo i projekt jest mały w porywach do średniego.

zrobiłem coś takiego jak poniżej - proste, że aż boli, ale o to chodzi:
  1. <?php
  2. function __autoload($class)
  3. {
  4. //Tablica potencjalnych lokalizacji klas php
  5. $paths=array(MODEL_DIR, MODEL_DIR.'dao/', HELPER_CLASSES_DIR, );
  6. foreach($paths as $path)
  7. {
  8. $file=$path. $class. '.php';
  9. if (file_exists($file))
  10. {
  11. require_once($file);
  12. }
  13. }
  14. }
  15. ?>


Jak widać rozwiązanie polega na wszytaniu wszystkich potencjalnych katalogów, w których znajdują się klasy php i następnie przeszukaniu ich w poszukiwaniu danej klasy.
Docelowo w projekcie będzie jakieś +/- 200 klas w 8-10 katalogach. Czy to rozwiązanie jest "ok" czy raczej niezbyt racjonalne - chodzi oczywiście o wydajność. Nie wiem jaki jest koszt przeszukania kilku katalogów - może lepiej zrobić mniej katalogów?

Co o tym myślicie. Dodam, że wolałbym uniknąć mapowania plików w tablicach itp - chodzi mi o bardzo proste i w miarę wydajne rozwiązanie.
Ludvik
Cytat
wolałbym uniknąć mapowania plików w tablicach

Kiedy to wydaje się być lepszym rozwiązaniem. Jeżeli napiszesz prosty system, to nie narazisz się na duże straty wydajności. Tak jak napisano w wątku dot. autoloaderów, __autoload nie zapycha serwera, jeżeli jest dobrze napisany. Przynajmniej tak jest w przypadku mapowania klas.
athabus
Tylko tutaj powstaje pytanie jaka jest graniczna wielkość aplikacji, kiedy to przestaje być sztuka dla sztuki. Czy 200 plików i taki system jak ja pokazałem przy średnio odwiedzanej witrynie rzeczywiscie "zapycha" serwer - w sensie czy generuje "zauważalny" wzrost pracy serwera?

Wiem że trudno to jakoś arbitralnie określić - są różne serwer, ale czy ogólnie takie podejście jak moje stanowi rzeczywisty problem. Oczywiste jest, że przy dużych systemach - typu framework - takie rozwiązanie nie ma racji bytu, ale czy jest sens tworzyć rozbudowane rozwiązanie dla małej/średniej witryny?
hwao
Mój autoloader działa troche inaczej.

Mianowicie został w nim zastosowany mechanizm liczacy ile razy dana plik jest potrzebny, jezeli wychodzi wiecej niz 80% automatycznie na starcie sobie je dolacza.

Ogolnie to pratycznie nie wykorzystuje __autoload() wole stosowac include wtedy kiedy wiem ze cos jest potrzebne
dr_bonzo
wow, zaimplementowales moja idee, chyba ja prezentowalem w tamtym watku smile.gif
athabus
Hwao a czy kod Twojego rozwiązania jest na licencji GPL lub pokrewnej ? winksmiley.jpg

A wracając do pytania to czy moje rozwiązanie jest :
a) Złe
cool.gif Złe od strony optymalizacji, ale przy małym projekcie nie spowoduje spcejalnie różnicy
bigZbig
@athabus - przy niewielkiej liczbie potencjalnych lokalizacji (najlepiej jednej) i malym projekcie to za duzej roznicy nie ma, jednak musisz sobie zdawac sprawe z tego, ze im wiecej podasz lokalizacji tym wiecej kazdorazowej niepotrzebnej pracy dla serwera. Moze zrob cos w rodzaju caschu. Pliki raz znalezione zapisuj w mapie i wyszukiwanie zaczynaj wlasnie od tej mapy, a jak dany plik nie znajduje sie w mapie lub podana jest bledna lokalizacja to przystepuj do przeszukiwania katalogow.

Tak na marginesie wspomne, ze z takiego jak ty masz rozwiazania skorzystali programisci Zenda we FrontControlerze, ktory poszczegolnych plikow z kontrolerami (klasami grupujacymi akcje) poszukuja wlasnie we wczesniej wskazanym katalogu.
athabus
Cytat(bigZbig @ 24.08.2006, 11:26 ) *
Pliki raz znalezione zapisuj w mapie i wyszukiwanie zaczynaj wlasnie od tej mapy, a jak dany plik nie znajduje sie w mapie lub podana jest bledna lokalizacja to przystepuj do przeszukiwania katalogow.

Hmm czemu sam na to nie wpadłem - proste, elastyczne i w miarę wydajne... Za mało kawy chyba biggrin.gif
Dzięki za pomysł - tak właśnie zrobię.

//edit zrobilem takie proste rozwiazanie, moze ktos madry rzuci okiem

Klasa jest singeltonem - dzieki temu nie trzeba wielokrotnie odczytywac i zapisycwac zmian -> zamiast tego jest flaga isChanged, ktora okresla czy destruktor ma zapisac plik z cachem sciezek.

@bigZbig Nie wiem czy dokladnie o to Co chodzilo, ale i tak jest to chyba lepsze rozwiazanie niz moj pierwszy post.

Kod Autoloadera

A tutaj przyklad uzycia - > specjalnie przeszukanie plikow wywalilem do __autoload i nie zawarlem w klasie, gdyz uznalem ze tak bedzie bardziej elastycznie
  1. <?php
  2. function __autoload($class_name)
  3. {
  4. $autoloader=Autoloader::getInstance();
  5. //autoloader zwraca true jesli uda mu sie includowac plik (plik
  6. //jest includowany wewnatrze obiektu autoloader.
  7. //jesli autoloader zwraca false znaczy, ze brak pliku w mapie i trzeba go poszukac
  8. if (!$autoloader->includeFile($class_name))
  9. {
  10. //tu nalezy podac wszystkie mozliwe sciezki, w ktorych bedziemy szukac plikow
  11. $paths=array(MODEL_DIR, MODEL_DIR.'dao/', HELPER_CLASSES_DIR, );
  12. foreach($paths as $path)
  13. {
  14. //nalezy podac sposob budowy nazw pliku ->tu poprostu nazwa_klasy.php
  15. $file=$path. $class_name. '.php';
  16. if (file_exists($file))
  17. {
  18. include_once($file);
  19. //w razie odnalezienia pliku dodajemy go do mapy, aby nastepnym razem juz
  20. //nie trzeba bylo szukac
  21. $autoloader->addItem($class_name, $file);
  22. }
  23. }
  24. }
  25. //tutaj ewentualny kod w razie nieodnalezienia klasy, np. informujacy o chwilowej 
    awarii itp
  26. die ('Niestety nastapily chwilowe problemy z dostepem do strony- prosimy sprobowac pozniej');
  27. }
  28. ?>


Kod jeszcze nie był specjalnie mocno testowany, ale wydaje się działać poprawnie. Będę wdzięczny za wszelkie sugestie
sf
@athabus: mam cos podobnego, tyle, ze heh, nei bardzo rozumiem idee wpychania na sztywno katalogow wewnatrz funkcji

wg. mnie lepiej zrobic tak na poczatku aplikacji :
  1. <?php
  2. $oAutoload = HAutoload::getInstance();
  3. $oAutoload->add('katalog/bla/', 'classesMap.php');
  4. $oAutoload->add('katalog2/bla/', 'classesMap.php');
  5. ?>


i potem w autload:
  1. <?php
  2. function __autoload($sName)
  3. {
  4. $oAutoload = HAutoload::getInstance();
  5. $aList = $oAutoload->export();
  6. // ...
  7. }
  8. ?>

}
athabus
Sam nie wiem, generalnie chodziło mi o to, że u mnie autoloader to w zasadzie kontener na mapę scieżek. Funkcja __autoload okresla wzor budowy pliku php i sciezki - nie chciałem też za każdym razem przekazywać wszystkich scieżek do Autoloadera, skoro i tak będzie z nich korzystał sporadycznie. No ale to taki szczegół. Twoje podejście jest bardziej zgodne z paradygmatem obiektowym.

//edti
czy ja dobrze rozumiem ze ty za pomoca funkcji eksport() zwracasz tablice ze sciezkami. Bo tak sie zastanawiam, co się dzieje jak zmieniasz polozenie katalogu. U mnie obiekt jest odpowiedzialny za to czy dany plik istnieje -> jesli nie istnieje we wskazanej lokalizacji to autaomatycznie lista sciezek jest aktualizowana. Jak to działa u Ciebie?
sf
Tak, export zwraca tablice sciezka => tabica z lista klas, sciezka => tablica z lista klas. I te tablice z lista klas laduja mniej wiecej takie pliki :
  1. <?php
  2. return array(
  3. 'DAOCompanies' => 'dbi/DAOCompanies.php',
  4. 'DAOUsers' => 'dbi/DAOUsers.php'
  5. // ...
  6. );
  7. ?>
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.