Quadric

Quadric

(4 comments, 58 posts)

This user hasn't shared any profile information

Posts by Quadric
img_68644c77ea5d1f6ae

PHP 5.3.3 i konstruktor

0

Podczas pracy nad frameworkiem napotkałem na bardzo dziwny błąd (jak mi się wtedy wydawało). Miałem klasę “Index” i metodę “index”. Podczas tworzenia instancji klasy ciągle mi się uruchamiała automatycznie ta metoda. Doszedłem chyba po 2 godzinach do tego, że to nie błąd tylko feature. Już tak dużo czasu minęło, że zapomniałem, że PHP traktuje metody o takiej samej nazwie jak klasa jako jej konstruktor. Trochę mnie to załamało, bo moje MVC jest oparte o takie założenie, a twórcy PHP zostawili taką możliwość jako wsteczną kompatybilność.

Na szczęście doczytałem, że od wersji PHP 5.3.3 zmieniło się zachowanie szukania konstruktorów i teraz tego typu metoda traktowana jest jako zwykła metoda a nie jako konstruktor. Uff!

ArDrone

0

Jako pasjonat zabawek i technologi…

…a zresztą, zobaczcie sami.

Wydajność dostępu do pól klasy

0

Przedstawiona teoria dotyczy wielu języków interpretowanych… m.in PHP i Python.

Jeżeli posiadasz złożone klasy zawierające wiele pól (czy to statycznych i dynamiczny) i w swoich metodach wykorzystujesz je dosyć często, np w ten sposób:

	public static function fetchAll($query = null, $args = array())
	{
		$sql = 'SELECT ' . static::$_columns . ' FROM ' . static::$_table . (isset(static::$_joinLeft[static::$_table]) ? static::$_joinLeft[static::$_table] : null);

		if ($query) {
			$sql .= ' WHERE ' . $query;
		}

		$collection = array();

		if (empty(self::$_selectQuery[static::$_table]) || self::$_selectQuery[static::$_table] != $sql) {
			self::$_selectStatement[static::$_table] = Database::getInstance(static::$_database)->prepare($sql);
			self::$_selectQuery[static::$_table] = $sql;
		}

		foreach($args as $k => $v) {
			self::$_selectStatement[static::$_table]->bindValue($k+1, $v);
		}

		self::$_selectStatement[static::$_table]->execute();

		// --

 		return $collection;
	}

to w takim przypadku system będzie każdorazowo musiał odpytać do pamięci o to pole. Niestety ale tak to działa. Można znacznie przyspieszyć wykonywanie tego kodu poprzez stworzenie lokalnej wartości, tak aby nie było konieczności każdorazowego odwoływania się do klasy. Zrobiłem szybki test w którym stworzyłem 4 klasy:

class A {

	public static $_a = 4;

	public function a() {

		$a = self::$_a;
		$b = self::$_a;
		$c = self::$_a;
		$d = self::$_a;
		$e = self::$_a;
		$f = self::$_a;

	}
}

class B {

	public static $_a = 4;

	public function a() {

		$local = self::$_a;
		$a = $local;
		$b = $local;
		$c = $local;
		$d = $local;
		$e = $local;
		$f = $local;

	}
}

class C {

	public $_a = 4;

	public function a() {

		$a = $this->_a;
		$b = $this->_a;
		$c = $this->_a;
		$d = $this->_a;
		$e = $this->_a;
		$f = $this->_a;

	}
}

class D {

	public $_a = 4;

	public function a() {

		$local = $this->_a;
		$a = $local;
		$b = $local;
		$c = $v;
		$d = $v;
		$e = $local;
		$f = $local;

	}
}

Jak widać nie robią one nic niesamowitego, ale robią w zasadzie to samo… tylko, że w różny sposób:

Test polegał na utworzeniu instancji i wywołaniu na każdej instancji 1 mln razy metody a()

Wyniki są następujące:

dla Windows

A: static 1.1116s
B: static with local 0.6764s
C: dynamic 0.9799s
D: dynamic with local 0.6258s

Jak widać, poprzez utworzenie zwykłej zmiennej, która ma dostęp lokalny uzyskujemy prawie 2x przyspieszenie wykonywania kodu.

PHP 5.3 – dirname(__FILE__) vs __DIR__

0

Jedną z najczęstszych optymalizacji kodu jest ładowanie plików z lokalizacji bezwzględnej gdyż ogranicza to konieczność przeszukiwania przez PHP ścieżek include_path. Skrypt, który wykonuje:

require 'd:/www/frame/dev/Core.php';

zadziała szybciej niż

require 'Core.php'

Dlatego przy dyrektywach require i include można najpierw zbadać położenie skryptu aby opracować ścieżkę dostępu. Najczęściej stosuje się polecenie:

$path = dirname(__FILE__);

w rezultacie otrzymamy katalog w którym znajduje się obecnie uruchomiony skrypt. W bardzo wielu systemach jest to używane. Jednakże od wersji PHP 5.3 istnieje stała __DIR__, która zwraca dokładnie to co powyższy kod. Dlaczego warto jej używać? Szybki benchmark:

ile trwa wywołanie po 1 mln razy:

__DIR__ 0.1562s
dirname(__FILE__) 0.4114s

Wynik nie powinien nikogo dziwić, zatem myślę, że warto się na tę stałą przestawić.

Atrybut Title w Internet Explorer – jak usunąć?

1

Ostatnio napotkałem na dość dziwny problem w przeglądarce Internet Explorer (a jakże) z atrybutem title. Miałem za zadanie stworzyć własny system wyświetlający podpowiedzi do danego wiersza w zestawie pól formularza. Naturalnym rozwiązaniem dla mnie było użycie atrybutu “title” Algorytm sprowadził się do tego, że na zdarzeniu :hover pobierałem atrybut title przekazywałem do mojego systemu a z tego usuwałem. Wszystko to wykonane było za pomocą jQuery

$('.row').hover(function() {
    var title = $(this).attr('title');
    $(this).removeAttr('title');
});

Wydawałoby się, że to dosyć proste i banalne, jednakże Internet Explorer zupełnie nie rozumie o co chodzi. Usunięcie atrybutu title zwyczajnie nie przynosi rezultatów. Chmurka od przeglądarki nadal się pojawia. Rozwiązanie jakie udało mi się wynaleźć to ustawienie title na wartość pustą

$('.row').hover(function() {
    var title = $(this).attr('title');
    $(this).attr('title', '');
});

I voila! Teraz Internet Explorer jak i inne przeglądarki nie mają problemu. Chmurka przestaje się pojawiać. Co ciekawe… jeśli jednak dodatkowo potem jeszcze usunę ten atrybut w ten sposób:

$('.row').hover(function() {
    var title = $(this).attr('title');
    $(this).attr('title', '');
    $(this).removeAttr('title');
});

to chmurka znowu się pojawia z oryginalnym tekstem. Wygląda na to, że ustawienie samodzielne title jakoby podmienia zawartość kontenera zatem usunięcie tego co sami zrobimy “odsłania” wartość pierwotną. Dziwne?

Pliki konfiguracyjne i aplikacje w PHP

0

Ostatnio po raz kolejny mierzę się z problemem przechowywania informacji konfiguracyjnych dla aplikacji napisanych w języku PHP. Jak to zrobić? Czego użyć? Co będzie najprostsze i najbardziej wygodne i przede wszystkim dla mnie…. co będzie najszybsze? Oczywiście chciałbym znaleźć złoty środek, który łączy wszystkie te cechy w jednym. Czy tak się da? Zobaczymy… ale najpierw mały wstęp:

Nie wszystko złoto co się świeci

PHP to taki dziwny język. Przez jednych kochany przez innych nienawidzony. Jednak jest w nim coś takiego co sprawia, że mnie cały czas zadziwia i ciągle uczę się o nim czegoś nowego. Ciekawe jest to, że pewne rzeczy, które wydawałoby się, że powinny działać lepiej/szybciej od innych zachowują się zupełnie odwrotnie.

Osoby, które mają jakieś pojęcie o językach takich jak np C i starają się pisać kod w sposób wydajny i pamięciooszczędny mają wyrobione pewne reguły postępowania, które pomagają ten cel przybliżyć takie jak:

  • wskaźniki do obiektów
  • zmienne właściwego typu
  • zarządzanie pamięcią
  • dyrektywa define
  • itd

Co ciekawe… z racji tego, że język PHP jest składniowo bardzo podobny do języka C++ a ponadto występują w nim podobne konstrukcje to naturalnym odruchem wydaje się chęć ich używania. Niestety tutaj możemy wpaść w pułapkę. Przede wszystkim trzeba sobie za każdym razem przypomnieć, że aplikacja w języku PHP i jego specyfika jest zupełnie inna niż ta w języku C. Weźmy na tapetę “define”. W jeżyku C taka konstrukcja #define PI  3.14 pozwala “nazwać” pewną stałą wartość np liczbę 3.14 nazwać PI i zamiast pisać w kodzie 3.14 używamy PI. Kompilator zamieni wszystkie wystąpienia PI na liczbę 3.14.  Dzięki temu uzyskamy bardzo wydajny kod, jednocześnie mając wszystko ładnie poukładane i pod kontrolą. Oczywiście można tworzyć o wiele bardziej skomplikowane rzeczy ale nie o to teraz chodzi. Wydawałoby się, że to samo można zastosować do PHP. Przecież tutaj tez mamy konstrukcję define(“PI”, 3.14); Jednakże tutaj pojawia się problem. Trzeba wziąć pod uwagę, że w aplikacji napisanej w jezyku C interesuje już nas samo uruchomienie. Natomiast w PHP na każde uruchomienie skryptu składa się komplikacja i wykonanie. W związku z tym, nie daje to żadnego przyspieszenia – a wręcz zwalnia to program. PHP więcej czasu potrzebuje na uruchomienie funkcji define niż stworzenie zwykłej zmiennej. Takie przykłady można mnożyć jednak po tym przydługim wstępie chciałem przejść do meritum:

Kod PHP wolniej działa w PHP

Nagłówek może nieco wydawać się enigmatyczny lub pozbawiony sensu ale istocie oddaje on całą prawdę. Okazuje się, że niektóre konstrukcje samego języka PHP mogą działać wolniej niż funkcje dostarczone do języka. Nawiązując do tematu tego posta stanąłem przed problemem zdecydowania się na system, za pomocą którego mógłbym przechowywać dane konfiguracyjne aplikacji w języku PHP (ściślej mówiąc projektowanego frameworka). Co mnie interesowało i wziąłem pod uwagę:

  1. Serializowana tablica
  2. JSON
  3. plik INI
  4. plik PHP z tablicą

Żeby zbyt wiele nie wróżyć postanowiłem przeprowadzić testy wydajnościowe. Format danych który chciałbym załadować to węzeł x1, który zawiera 2 pary wartości y1 = 1 oraz y2 = 2 oraz węzeł x2, który zawiera 2 pary y3= 1 oraz y4 = 2

Dla każdej z metod zapisałem dane w odpowiednim formacie:

serializowana tablica

a:2:{s:2:”x1″;a:2:{s:2:”y1″;s:1:”1″;s:2:”y2″;s:1:”2″;}s:2:”x2″;a:2:{s:2:”y3″;s:1:”1″;s:2:”y4″;s:1:”2″;}}

JSON
{“x1″:{“y1″:”1″,”y2″:”2″},”x2″:{“y3″:”1″,”y4″:”2″}}

plik INI
[x1]
y1 = 1
y2 = 2
[x2]
y3 = 1
y4 = 2

plik PHP z tablicą
$conf_2 = array(
‘x1′ => array( ‘y1′ => 1, ‘y2′ => 2 ), ‘x2′ => array( ‘y3′ => 1, ‘y4′ => 2 ));

Procedura testowa

Test polegał na 10000 krotnym wywołaniu danej funkcji i odczytaniu danych. Dla każdej z metod wykonałem odpowiednie procedury:

serializowana tablica

$conf_3 = unserialize(file_get_contents(‘./array.ser’));

JSON
$conf_5 = json_decode(file_get_contents(‘./array.json’), TRUE);

plik INI
$conf_1 = parse_ini_file(‘./array.ini’, true);

plik PHP z tablicą
require(‘./array.php’);

Wyniki testu

Windows 7 (PHP 5.3.1)

  1. Plik INI (0.9728s)
  2. Require (1.0595s)
  3. Unserialize (1.0884s)
  4. JSON (1.1447s)

Linux (PHP 5.3.6)

  1. JSON (0.1267s)
  2. Plik INI (0.1744s)
  3. Unserialize (0.1892s)
  4. Require (0.2466s)

Podsumowanie

W tym momencie ciężko wyłonić zwycięzce. Dziwi mnie tylko tak duża różnica w wydajności działania funkcji json_decode między platformą Windows i Linux. Co prawda nie jest to ta sama wersja PHP ale nie powinno to mieć wpływu na działanie tej funkcji. Test ten wskazuje prędkość działania konkretnych rozwiązań, ale nie mówi on nic o czytelności i łatwości korzystania a tutaj nie trudno wskazać zwycięzce – moim zdaniem plik INI jest w tej kwestii bezkonkurencyjny. Po pierwsze większość edytorów koloruje składnie plików INI. Poza tym (co może być uważane także za minus) można w nim stworzyć tylko rzeczy, które służą strice do konfiguracji – a więc nie ma obawy, że ktoś przecholuje i zacznie wrzucać tam jakieś funkcje, dziwne zależności, zmienne globalne itd. Poza tym parser plików INI w PHP potrafi także interpretować stałe (np E_NOTICE –  tak jakby widział je w kodzie) oraz przechowywać tablice. Jedyny minus to taki, że nie potrafi on skonwertować danych na rzeczywiste typu… np “true” to nie będzie w PHP “true” tylko “1″ .. każda inna nieprawda  to będzie pusty ciąg znaków.

Ponadto widać tu także inną rzecz. Wykonanie funkcji “parse_ini_file”, która uruchamia funkcję mającą zaczynać plik z dysku, sparsować i pozmieniać jego dane na format rozpoznawalny przez PHP działa szybciej niż załadowanie już gotowego formatu danych PHP z pliku PHP za pomocą instrukcji języka. Dziwne? I tak nie. parse_ini_file jest funkcją napisaną w języku C przez co wykonuje się ona zdecydowanie szybciej niż instrukcja PHP. Myślę, że istnieje jeszcze wiele takich króczków i na pewno będę je dalej badał.

Chciałbym jeszcze wspomnieć, że oczywiście zdaję sobie sprawę z istnienia akceleratorów, optcode’u, gotowych klas parsujących (np w Zend Framework) języka YAML, memcache’a itd itd, ale chciałem w czystym środowisku ukazać specyfikę samego języka PHP aby poznać skąd się co wzięło i z czego wynika. Jeśli nie jesteśmy zmuszeni aby używać systemu poprawiającego działanie innego systemu to dobrze. W programowaniu im mniej skomplikowany algorytm tym lepiej.

GTX 580 – najszybszy układ DX11 na świecie?

0

Udało mi się w sieci znaleźć filmik na którym Tom Petersen prezentuje nową technologię NVIDIII. Przyznam, że prezentacja naprawdę w sposób ciekawy i interesujący prezentuje możliwości nowego układu. Na mnie szczególne wrażenie zrobił moment w którym przełączono mapę miasta w trym “wireframe”. Widać tutaj prawdziwą potęgę karty w obsłudze teselacji.

xbox-livexboxblog9083213

Xbox Live w Polsce!

0

Dzisiaj oficjalnie ruszył Xbox Live w naszym kraju. Niestety jak można było się spodziewać osoby, które najgłośniej krzyczały, że “co to ma być, że w Polsce nie ma xbox live”, teraz psioczą na forach i wątkach, że “a w PL live nie ma tego, nie ma tamtego”, “punky są drogie”, “kody są drogie” itd itd. Z tymi wysokimi cenami to niestety prawda, ale warto może dać jeszcze się temu trochę rozwinąć i ustabilizować. Narzekanie na brak pewnych usług jest już moim zdaniem totalnym zagraniem “nie fair” – ale taka jest już niestety polska mentalność narzekania na wszystko i ciągłego “mi się należy. Na szczęście wraz z wprowadzeniem usługi w Polsce utrzymujemy możliwość migracji konta z innego kraju więc nie ma większych przeszkód by osoby, które mają już nabite na swoje konto osiągnięcia, content czy punkty MS mogły sobie przenieść to na PL wersję.

Ja jako patriota oczywiście przeniosę konto na PL i polecam wszystkim tę operację. Pokażmy, że społeczność Xbox’a w Polsce jest i że warto się dla tej społeczności trochę postarać.

Do zobaczenia na Xbox Live!

Ustawianie Cookie w Internet Explorer na localhost

0

Ostatnio miałem dużą zagwostkę związaną z tym, że Internet Explorer na localhoście nie chciał zapisywać plików cookie. Jeżeli także zmagasz się z takim problemem to jest bardzo ciekawa przyczyna: IE nie zapisuje ciastek gdy domena localhosta posiada podkreślniki w naziwe “_”.

Usunięcie podkreślinków z nazwy rozwiązało problem :)

Xbox 360 Elite

Nowy Xbox 360 – wrażenia

0

Od kilku dni jestem szczęśliwym posiadaczem nowej konsoli Xbox 360 “Slim” – przyjęło się mówić tak na nią chociaż nie jest to oficjalna nazwa ani wcale zbytnio slim ta konsola nie jest. Chciałbym się podzielić moimi spostrzeżeniami i porównaniem do konsoli w wersji Elite, którą miałem poprzednio.

Design

Wygląd to oczywiście rzecz gustu, ale przyznam, że wolałem poprzednią wersję – może to kwestia przyzwyczajenia? Nowy Xbox jest jakiś taki kanciaty, chłodzenie wygląda jakby było stylizowane na starych oldsmobilach – co również nie wszystkim przypadnie do gustu.

Wersja Xbox 360 Elite

  1. Matowa obudowa
  2. Dysk 120 GB
  3. Brak Wifi
  4. Napęd DVD
  5. Technologia wykonania 65nm
  6. GamePad
  7. Przyciski mechaniczne
  8. Zestaw słuchawkowy
  9. Kabel HDMI
  10. Kabel Ethernet
  11. Złączka SCART
  12. Kabel Composite
  13. Zasilacz
  14. Analogowe wyjście dźwięku
  15. Waga ok 5kg

Wersja Xbox 360 S

  1. Połyskliwa obudowa
  2. Dysk 250 GB
  3. Wbudowane Wifi
  4. Napęd DVD
  5. Technologia wykonania 45nm
  6. GamePad (nowy design)
  7. Przyciski dotykowe
  8. Zestaw słuchawkowy
  9. Brak kabla HDMI
  10. Brak kabla Ethernet
  11. Złączka SCART
  12. Kabel Composite
  13. Zasilacz z wentylatorem
  14. Cyfrowe wyjście dźwięku
  15. Waga ok 4kg

GamePad

Na pierwszy rzut oka tego nie widać, ale odświeżony został także gamepad. Szare przyciski sticków i dpada zmieniono na kolor czarny,

Wersje

Z tego co udało mi się wybadać, na dzień dzisiejszy planowane są 3 wersje:

  1. Wersja połyskliwa z 250 GB dyskiem
  2. Wersja matowa z 4 GB dyskiem
  3. Wersja matowa z 4 GB dyskiem i kontrolerem kinect

UWAGA! Sprawdźcie dokładnie co kupujecie i uważajcie na promocje w sklepach. Pudełka poszczególnych wersji praktycznie niczym się nie różnią. Jest tylko symbol 4 GB lub 250 GB w górnym rogu i matowa obudowa – gdy 2 pudełka nie stoją blisko siebie można się łatwo pomylić. Podejrzewam, że pudełko wersji z kinectem będzie nieco większe – ale tu uwaga – też będzie tam tylko 4 GB.

Widziałem także już limitowane wersje “kolekcjonerskie” tj z grami albo z jakimś ciekawym kolorem czy wzorem obudowy, ale takie coś ciężko zdobyć.

Wrażenia

Nowy Xbox jest na pewno cichszy. Zużywa mniej prądu. Dotykowe przyciski są ciekawym rozwiązaniem – ponadto naciśnięcie ich wywołuje określone sygnały dźwiękowe. Konsola ładnie się prezentuje (ale to oczywiście kwestia gustu). Kontroler Wifi działa bez zarzutu. Wkurza natomiast brak kabla HDMI

Samo użytkowanie konsoli niczym się w zasadzie nie różni. Jest to dalej ten sam dobry xbox – tylko odświeżony. Uważam, że spełnia dzisiejsze wymogi i standardy. Spotkałem się z opiniami, że wielkim minusem jest brak odtwarzacza blueray. Chciałbym tylko przypomnieć, że xbox 360 to konsola a nie PC. Nie można w konsoli wprowadzić jakiegoś rozwiązania, które otwiera możliwości tylko pewnej wąskiej grupie użytkowników. Nie można w konsoli wymienić procesora na szybszy, dać więcej pamięci, zmienić nośniki danych na zupełnie co innego i nazywać to dalej Xbox 360. Rzeczywiście może denerwować żonglowanie płytami DVD w niektórych grach ale bez przesady. Np w Mass Effect 2 zdarzyło mi się to 4 razy przez całą grę (ponad 70h gry)

Czy warto kupić nowego Xbox’a jeśli jeszcze nie masz konsoli? Tak. Xbox 360 jest bardzo dobrą konsolą. Z doskonałym rynkiem usług (na jesieni 2010 dostępnym oficjalnie w Polsce). Bardzo dużą ilością gier i pojawia się ich coraz więcej. Niektóre tytuły to tzw Exclusive – czyli dostępny wyłącznie na tę konsolę. Jeśli nigdy nie grałeś na konsoli tylko na PC musisz przekonać się, że jest to zupełnie inne doświadczenie.

Czy warto kupić nowego Xbox’a jeśli masz już konsolę Xbox 360? To zależy. Jeśli wymienione przeze mnie zmiany i nowości spowodowały przyspieszenie rytmu Twojego serca to zdecydowanie tak. Jeśli boisz się, że zostaniesz w tyle i nie będziesz miał możliwości skorzystania w przyszłości ze wszystkich usług jakie będzie oferował Xbox to spokojnie:

  1. Dysk 250 zrobili także do starszej wersji i można go kupić oddzielnie
  2. Kontroler wifi można dokupić oddzielnie
  3. Kinect będzie można podłączyć do starszej wersji bez problemu. Trzeba będzie tylko podłączyć osobne zasilanie a w nowej wersji jest po prostu dedykowany port do tego.
Quadric's RSS Feed
Go to Top