Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Klasa do ładowania plików, duże obciążenie...
cojack
post
Post #1





Grupa: Zarejestrowani
Postów: 898
Pomógł: 80
Dołączył: 31.05.2008

Ostrzeżenie: (20%)
X----


No więc tak, mam sobie klasę do ładowania plików, i gdy odpaliłem profilera php to zobaczyłem że dość duże obciążenie mam na tej klasie, bo z wszystkich wywołań metod wszystkie wywołania a jest ich 33 z tego co dobrze widzę, klasyfikują na 2 miejscu w stopniu najbardziej obciążającym system, no i szczerzę powiedziawszy to nie mam bladego pojęcia co jest tak mega super złego w tej klasie że takie obciążenie powoduje, oto kod:

  1. <?php
  2. /**
  3.  * BDT_Loader klasa odpowiedzialna za ładowanie plików
  4.  *
  5.  * @author Przemysław Czekaj <przemyslaw.czekaj@aichra.pl>
  6.  * @version 0.1
  7.  * @since 03.29.2010
  8.  * @package BDT
  9.  * @subpackage lib
  10.  * @charset utf8
  11.  **/
  12.  
  13. /**
  14.  * @author cojack
  15.  * @TODO Błędy w postaci GETTEXT
  16.  */
  17. class BDT_Loader {
  18.  
  19. private static $_path;
  20.  
  21. /**
  22.   * Konstruktor klasy
  23.   *
  24.   * @return void
  25.   */
  26. public static function initialize() {
  27. chdir( './..' );
  28. self::$_path = getcwd() . '/';
  29. }
  30.  
  31. /**
  32.   * Metoda przyjmuje argument jako tablice iteracyjną
  33.   * Adres do pliku powinien zaczynać się od ./ i uwzględnić
  34.   * zmianę ścieżki podczas wczytywania danych.
  35.   * Zachowywujemy się tak jakbyśmy byli w / tego fw.
  36.   *
  37.   * @access public
  38.   * @param array $files Tablica w postaci array ('plik', 'plik', 'plik');
  39.   * @return void
  40.   */
  41. public static function loadFile( $files = array() ) {
  42. foreach( $files as $file ) {
  43. if( self::_checkFile( $file ) ) {
  44. require_once( self::$_path.$file );
  45. }
  46. }
  47. }
  48.  
  49. /**
  50.   * Metoda wczytuje pojedyncze pliki XML
  51.   *
  52.   * @access public
  53.   * @param string $files Względna ścieżka do pliku
  54.   * @return object Xml object
  55.   */
  56. public function loadFileXML( $file ) {
  57. if( self::_checkFile( $file ) ) {
  58. libxml_use_internal_errors( TRUE );
  59. $sxe = new SimpleXMLElement( self::$_path.$file, NULL, TRUE );
  60. if( $sxe === FALSE ) {
  61. $errorMsg = 'Błąd w pliku XML: ' . $file . "<br />";
  62. $errorMsg .= 'Ścieżka: ' . self::$_path.$file . "<br />";
  63. foreach( libxml_get_errors() as $error ) {
  64. $errorMsg .= "<p>" . $error->message . "</p><br />";
  65. }
  66. trigger_error( $errorMsg , E_USER_WARNING );
  67. }
  68. }
  69. return $sxe;
  70. }
  71.  
  72. /**
  73.   * Metoda sprawdza czy dany plik jest możliwy do wczytania
  74.   *
  75.   * @param string $file Względna ścieżka do pliku
  76.   * @return boolean true, false
  77.   */
  78. private static function _checkFile( $file ) {
  79. if( is_file( self::$_path.$file ) ) {
  80. if( is_readable( self::$_path.$file ) ) {
  81. return TRUE;
  82. } else {
  83. trigger_error( 'Plik: '. $file . ' jest nie dla odczytu, sprawdź uprawnienia.' , E_USER_WARNING );
  84. }
  85. } else {
  86. trigger_error( 'Zła ścieżka i/lub nazwa dla pliku: '. $file . "\n" . 'Ścieżka: ' . self::$_path . $file , E_USER_WARNING );
  87. }
  88. return FALSE;
  89. }
  90. }


Gdyby ktoś mógł mi wskazać jakieś wskazówki by poprawić wydajność tej klasy, będę wdzięczny, pomysły z autoload zachować dla siebie, od razu mówię nie, nie i jeszcze raz nie, także bez nich.

Ten post edytował cojack 23.08.2010, 20:18:19
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
wookieb
post
Post #2





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




Cytat(erix @ 24.08.2010, 10:04:26 ) *
  • w funkcji ładującej możesz zrobić cache w zmiennej statycznej i sprawdzać via in_array. IMO będzie szybsze niż odwoływanie się do funkcji I/O

Wiem, że w php-ie można spodziewać się różnych krzaków ale no sorry erix :/
  1.  
  2. class Loader
  3. {
  4. private static $loaded = array();
  5.  
  6. public static function load($file)
  7. {
  8. if (!in_array($file, self::$loaded))
  9. {
  10. require $file;
  11. self::$loaded[] = $file;
  12. }
  13. }
  14. }
  15.  
  16. $start = microtime(true);
  17. for ($i=0; $i<1000; $i++)
  18. {
  19. require_once 'test2.php';
  20. }
  21. echo microtime(true) - $start;
  22. echo '<br/>';
  23.  
  24. $start = microtime(true);
  25. for ($i=0; $i<1000; $i++)
  26. {
  27. Loader::load('test2.php');
  28. }
  29. echo microtime(true) - $start;
  30.  

Wynik
Kod
test0.0037469863891602
test0.050887823104858

Gdzie test jest zawartością pliku test2.php

Oczywiście, że require_once jest wolniejsze od require ale tylko przy pierwszym wywołaniu. I teraz pytanie. Czy warto się męczyć o zysk 1 setnej sekundy? I to w dodatku z ryzykiem wielu błędów (jeżeli nie korzystamy z autoloadera)? Nie sądzę.

Napomnę jeszczę taką kwestię iż nie zawsze korzystanie z funkcji autoloadera będzie ok.
Czasem w nagłówkach klas z łapy podaje się require_once i ścieżkę do pliku, żeby nie szukał jej autoloader.

Prosiłbym jeszcze kogoś o przetestowanie powyższego kodu z jakimś akceleratorem. Ponieważ APC mi nie działa na windowsie :/

Ten post edytował wookieb 24.08.2010, 10:56:04
Go to the top of the page
+Quote Post

Posty w temacie


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: 27.12.2025 - 12:47