Winuser's Blog

18 listopada 2010

C++ kontra PHP

Filed under: C++,PHP,Programowanie,Projekty,WWW — winuser @ 9:42
Tags: , , , , ,

Tak jak ostatnio obiecałem, tak oto zamieszczam moje przemyślenia / badania kwesti wydajności programów kompilowanych (C++) oraz skryptów (PHP). Jest sprawą oczywistą że walka jest nierówna, że porównanie może nie mieć sensu, że te języki stworzono do innych zadań. Ale olejmy na chwilę te wszystkie gadki, jak naprawdę przekłada się to co mówią ludzie na prawdziwe pomiary ? Sprawdziłem to i w tym wpisie można przeczytać efekty tego. Zamieszczam również kod klasy C++ do mierzenia czasu wykonania funkcji czy bloku programu. Zasady sprawdzania były proste, postawiony serwer www z użyciem popularnego pakietu WebServ (do testowania skryptu PHP) oraz skompilowany program C++ (użyłem kompilatora G++) w wersji release wrzucony do folderu CGI-BIN, odpalany z poziomu przeglądarki internetowej Opera. Na pierwszy ogień poszła konktatencja napisów. Żeby walka była wyrównana (zresztą nie może i tak być o wyrównanej walce mowy), to w kodzie C++ użyłem klasy std::string zamiast zwykłych wskaźników char, bo wynik mógłby się okazać wręcz miażdżący dla PHP. Niestety nawet mimo tego się taki okazał.. Wynik PHP: ~27 sekund, wynik C++: ~1.8 sekundy. Kod programu C++ :

#include <iostream>
#include <string>

#include "PerformanceTimer.h"

using namespace std;

int main()
{
	cout << "Content-type: text/html" << endl << endl;
	cout << "<html><head><title>Obliczanie</title>";
	cout << "</head><body>" << endl;
	cout << "<h1>Wyniki obliczen</h1>";
	
	PerformanceTimer pt;
	string napis;
	
	pt.Start();
	for (int i = 0; i < 100000000; i++)
	{
		napis += i;
	}
	pt.Stop();
	
	cout << (pt.GetTime() / (double)10000000) << endl;
	cout << "</body></html>";
	
	return 0;
}

Skrypt PHP:

<html>
	<head>
		<title>Obliczanie</title>
	</head>
	<body>
		<h1>Wyniki obliczen</h1>
		<?php
			$starttime = microtime(true);
			for ($i = 0; $i < 100000000; $i++)
			{
				$napis += $i;
			}
			$stoptime = microtime(true);
			
			echo round($stoptime - $starttime, 5);
		?>
	</body>
</html>

Wykonywanie kodu tego typu (tak wielka ilość iteracji) nie zdarza się raczej zbyt często, aczkolwiek daje pewien obraz sytuacji. W pierwszym teście to, który wygra dość łatwo można było przewidzieć. Ale co gdybyśmy chcieli potestować odczyt i zapis do pliku ? Sprawdziłem. Tym razem testowałem trzy rzeczy, pierwsza odczyt plików i zapis w PHP, druga to odczyt i zapis z użyciem strumieni C++, ostatnia rzecz którą testowałem to odczyt oraz zapis pliku z użyciem funkcji API systemu Windows. Wyniki tym razem nie są już aż tak miażdżące, lecz nadal odrazu widać który sposób jest wydajniejszy. W celu lepszego zobrazowania sytuacji stworzyłem wykres. Jest on wyskalowany w sekundach. Rozmiar pliku na którym testowane były operacje zapis / odczyt można w prosty sposób obliczyć: rozmiar_bufora * ilosc_iteracji = ~ 125 MB.

Dołączam równiez kod C++ użyty do odczytu / zapisu Win32 :

#include <iostream>
#include <string>

#include "PerformanceTimer.h"

using namespace std;

int main()
{
	cout << "Content-type: text/html" << endl << endl;
	cout << "<html><head><title>Obliczanie</title>";
	cout << "</head><body>" << endl;
	cout << "<h1>Wyniki obliczen</h1>";
	
	PerformanceTimer pt;
	DWORD dwWrite;
	
	HANDLE hFile = CreateFile("plik.bin",
							  GENERIC_READ | GENERIC_WRITE,
							  0,
							  0,
							  CREATE_ALWAYS,
							  0,
							  0);
	char szBuffer[255];
	memset(&szBuffer, 0, sizeof(szBuffer));
	
	pt.Start();
	for (int i = 0; i < 500000; i++)
	{
		WriteFile(hFile, szBuffer, sizeof(szBuffer), &dwWrite, 0);
	}
	pt.Stop();
	
	cout << (pt.GetTime() / (double) 10000000) << endl;
	CloseHandle(hFile);
	
	hFile = CreateFile("plik.bin",
					   GENERIC_READ | GENERIC_WRITE,
					   0,
					   0,
					   OPEN_EXISTING,
					   0,
					   0);
	
	pt.Start();
	for (int i = 0; i < 500000; i++)
	{
		ReadFile(hFile, szBuffer, sizeof(szBuffer), &dwWrite, 0);
	}
	pt.Stop();
	
	cout << (pt.GetTime() / (double) 10000000) << endl;
	CloseHandle(hFile);
	
	cout << "</body></html>";
	return 0;
}

Kod użyty do odczytu / zapisu z użyciem strumieni :

#include <iostream>
#include <fstream>
#include <string>

#include "PerformanceTimer.h"
		
using namespace std;

int main()
{
	cout << "Content-type: text/html" << endl << endl;
	cout << "<html><head><title>Obliczanie</title>";
	cout << "</head><body>" << endl;
	cout << "<h1>Wyniki obliczen</h1>";
	
	PerformanceTimer pt;
	char szBuffer[255];
	ofstream file;
	
	memset(&szBuffer, 0, sizeof(szBuffer));
	file.open("plik.bin");
	
	pt.Start();
	for (int i = 0; i < 500000; i++)
	{
		file << szBuffer;
	}
	pt.Stop();
	
	file.close();
	cout << (pt.GetTime() / (double) 10000000) << endl;
	
	ifstream file_2("plik.bin");
	
	pt.Start();
	for (int i = 0; i < 500000; i++)
	{
		file_2.read(szBuffer, sizeof(szBuffer));
	}
	pt.Stop();
	
	file_2.close();
	cout << (pt.GetTime() / (double) 10000000) << endl;

	cout << "</body></html>";
	return 0;
}

A to kod dla PHP :

<html>
	<head>
		<title>Obliczanie</title>
	</head>
	<body>
		<h1>Wyniki obliczen</h1>
		<?php
			for ($i = 0; $i < 255; $i++) $buffer .= "6";
			
			$file = fopen("plik.bin", "w");
			flock($plik, LOCK_EX);
			
			$starttime = microtime(true);
			for ($i = 0; $i < 500000; $i++)
			{
				fwrite($file, $buffer);
			}
			$stoptime = microtime(true);
			
			flock($file, LOCK_UN);
			fclose($file);
			echo round($stoptime - $starttime, 5) . "<br/>";
			
			$file = fopen("plik.bin", "r");
			flock($file, LOCK_SH);
			
			$starttime = microtime(true);
			for ($i = 0; $i < 500000; $i++)
			{
				fread($file, 255);
			}
			$stoptime = microtime(true);
			
			echo "<br/>" . round($stoptime - $starttime, 5) . "<br/>";
			flock($file, LOCK_UN);
			fclose($file);
		?>
	</body>
</html>

Na koniec mała konkluzja tego testu. Od początku wierzyłem że lepsze wyniki uzyska program pisany w C++ i tak też się okazało. Lecz żeby było ciekawiej, to dodam, nie zawsze wyniki uzyskiwane były tak dobre. Nie wiem od czego to zależy, w każdy razie program uruchamiany osobno (nie poprzez serwer www na żadanie przeglądarki) uzyskiwał stabilniejsze i krótsze czasy. Czasem nawet o 1/3. A w przypadku zapisu do pliku wyniki okazywały się być nawet gorsze (!). Mimo tego jednak uważam, że używanie programów CGI kompilowanych może znacząco podnieść wydajność treści dynamicznej, aczkolwiek jest bardziej złożone niż zwykły skrypt w PHP. Ten test nie miał za zadanie oczywiście w żaden sposób pokazać wyższości jednego języka nad drugim. Obydwa lubię i tak już zostanie. Potraktujcie ten test raczej jako ciekawostkę, bo raczej chyba nikt nie będzie pisał www z użyciem C++.
Kod klasy PerformanceTimer można pobrać z pod tego adresu : http://sourceforge.net/projects/performancetime/files/PerformanceTimer.cab/download Jest to klasa napisana z użyciem kodu zawartego w książce „Windows via C/C++” i ja ten kod opakowałem w klasę aby było wygodniej.

Reklamy

10 września 2010

Narzędzie do automatycznego startu serwera GTA San Andreas MP

Filed under: C++,Programowanie,Projekty — winuser @ 15:21
Tags: , , , , ,

Na pewnym forum ktoś napisał że utrzymuje serwer GTA San Andreas multi-player, a ja jako że dość często zdarza mi się grywać w tą gierkę, postanowiłem mu pomóc w jego problemie. Mianowicie potrzebował on narzędzia które automatycznie uruchomi proces serwera gry po jego crashu. Nie jest to skomplikowana aplikacja. Napisana została z użyciem VCL (GUI) i funkcji API Windowsa (obsługa procesów, zdarzeń i wątków). Aplikację można pobrać stąd :  https://sourceforge.net/projects/sa-mp-autorun/files/GTA_SA_mp_autostart.cab/download

Aby aplikacja działała jak należy, trzeba wskazać położenie pliku sa_mp_server.exe (czy jak on się tam nazywał bo nie pamiętam 😛 ) i nacisnąć „start”. W momencie kiedy nastąpi crash aplikacji, automatycznie zostanie ona uruchomiona ponownie. Tak samo jeśli ktoś ubije proces serwera. Aby zakończyć go, trzeba poprostu kliknąć „Zakończ” w oknie mojej aplikacji.

23 sierpnia 2010

Kolejny reupload aplikacji Tlen-Prowokator

Filed under: C++,Programowanie,Projekty — winuser @ 20:35
Tags: ,

Poprzednie pliki zostały usunięte z serwisów hostingowych, a jako że po statystykach bloga widzę że zainteresowanie aplikacją nie maleje, dlatego postanowiłem wrzucić aplikację na coś pewniejszego (tutaj SourceForge.net) https://sourceforge.net/projects/tlen-prowokator/files/Tlen-Prowokator-v0-1-1.cab/download

Cheers !

18 sierpnia 2010

Poszukiwany grafik do małego projektu

Filed under: C++,Programowanie,Projekty — winuser @ 9:09
Tags: , , , , , ,

Ostatnio w wolnym czasie zacząłem sobie pisać dwa projekty. Pierwszy to klasa do obsługi gniazd (z opcją SSL) i zdarzeniami, która jest napisana w około 50 %. Drugi projekt który będzie tematem tego wpisu, to gra 😀 Jest to popularna gra w statki. Kiedy byłem dzieckiem zawsze w to grałem z kolegami / rodzeństwem. Gra odbywała się na kartkach papieru. Postanowiłem ją przenieść do komputera. Oczywiście zdaję sobie sprawę że takie gry dzisiaj tworzą o niebo lepsze, ale tworzenie jej to przecież tylko forma rozrywki 😉

Aplikacja jest pisana w języku C++, z wykorzystaniem windows API  (GDI, winsock). Ano właśnie do czego winsock ? Bo będzie to gra sieciowa. Na chwilę obecną mam już gotowe plansze i ogólnie jakiś tam interfejs. Ale. Nie byłoby tego posta gdyby nie pewna ważna sprawa. Otóż ja sam grafikiem jest raczej marnym, dlatego poszukuję osoby która by mi wykonała obrazki statków (rzut z góry). Potrzebne będzie dokładnie 5 rodzajów statków. Dla kogoś kto orientuje się w grafice to pewnie nic trudnego, dla mnie natomiast coś niewykonalnego 😛 Oczywiście osobę tę umieściłbym w stronie „O programie” w poczecie autorów. Tak więc, jeśli ktoś jest chętny to piszcie w komentarzach. Obrazki nie muszą (nawet nie mogą) być przesadnie realistyczne. Przydały by się tutaj raczej zdolości „pixelart”a.

A oto dwa screeny z nie ukończonej gry. Plansza główna :

Zrzut okna rozpoczynania nowej gry :

19 lipca 2010

Klasa SMTP (Simple Mail Transfer Protocol) z obsługą TLS – wysyłanie email z poziomu C++

Filed under: C++,Programowanie,Projekty — winuser @ 9:29
Tags: , , , , ,

Jakiś czas temu (liczony w miesiącach a może nawet dawniej) potrzebowałem nie skomplikowanej klasy do obsługi wysyłania email poprzez prokół SMTP w języku C++. Ostatnio wraz z kolegą pracujemy nad pewnym projektem no i potrzeba wróciła. Dlatego powstała ta klasa, a w sumie dwie. Jeszcze aby wszystkiego stało się zadość, dodam że klasa ta powstała w oparciu o kod do obsługi SMTP w języku C który znajduje się tutaj http://www.muquit.com/muquit/software/mailsend/mailsend.html Ile kodu skopiowano z wspomnianej wyżej biblioteki mailsend ? Otóż ja niczego nie kopiowałem 😛 Spojrzałem jedynie na jakiej zasadzie to wygląda i zaimplementowałem po swojemu. Tak więc mogę powiedzieć że jestem autorem kodu który tutaj przedstawiam. W zasadzie jest to moje drugie podejście do klasy SMTP, poprzednie mimo że zwieńczone sukcesem to jednak nie obsługiwało TLS, dlatego koncepcja została zmieniona, została napisana klasa Sock która służy do komunikacji TCP, oparta o Winsock 2 i bibliotekę OpenSSL. W tym wydaniu klasy obsługuje ona już m.in gmail.com (czyli połączenie z użyciem TLS) i wszelkie inne typu o2.pl. Całość jest bajecznie prosta, jako że protokół SMTP jest protokołem tekstowym i bardzo łatwo zrozumieć o co w nim wogóle chodzi.

Jeśli chodzi o klasę, to została w niej zaimplementowana tylko podstawowa funkcjonalność SMTP, a więc zalogowanie przy użyciu AUTH LOGIN oraz wysłanie wiadomości. Klasa korzysta z biblioteki OpenSSL, którą należy pobrać i zbudować dla używanego kompilatora, pobrać ją można z pod adresu http://www.openssl.org/ w sieci jest wiele poradników jak budować tą bibliotekę (tak, miałem z tym problem :D). Po wprowadzeniu pewnych zmian, klasa powinna działać również na UNIX`ach (chodzi tutaj głównie o klasę Sock). Dlatego jest *prawie* cross-platformowa 😛 No to tyle.

PS. Nie wyrażam zgody na używanie klasy w komercyjnych projektach. Wszelkie spostrzeżenia i uwagi proszę umieszczać w komentarzach.

Link do kodu  http://www.filefactory.com/file/b2a44bb/n/secure_smtp.cab Niestety jak nie będziecie pobierać to link zdechnie 😉 W razie czego proszę o info.

Musiałem wyedytować ten post, poprzednio kod uploadowałem na serwis fileimport.com, miał być 60 dni ale oczywiście na drugi dzień został usunięty. Tak więc szczerze nie polecam serwisu do hostingu plików fileimport.com !

Dopisek numer2. Zmodyfikowałem kod tak aby możliwe było jego działnie bez biblioteki OpenSSL. Wystarczy zdefiniować globalnie jeden symbol – SLL_ENABLED lub też go nie definiować. Wtedy w zależności od tej stałej będą włączane nagłówki i używane funkcje SSL. Oczywiście po wyłączeniu obsługa np. Gmail.com już nie będzie możliwa.

 

Link do źródła klasy : http://s1.katowice.pl/files/secure_smtp.cab

18 lutego 2010

Reupload aplikacji Tlen Prowokator

Filed under: Programowanie,Projekty — winuser @ 8:41
Tags: , ,

Jako że serwis filefactory.com jednak usuwa pliki po jakimś okresie nieużywania, to oczywiście moja aplikacja straciła się. Wrzuciłem więc ją na nowy serwer abyście mogli sobie pobierać bez problemów. Adres : http://files0.myftp.org/backup/arc/prowokator.rar

10 listopada 2009

Tlen Prowokator 0.1 – gotowy

Filed under: C++,Programowanie,Projekty — winuser @ 21:46

A więc tak jak obiecywałem, że zajmę się projektem w najbliższym czasie, tak skończyłem wersję 0.1 Archiwum zawiera plik pomocy który dogłębnie tłumaczy sposób obsługi aplikacji. A oto zrzut ekranu gotowej do pracy aplikacji : screen prowokator Całość została napisana z użyciem Windows API. Kompilator to GNU GCC (C++), a środowisko programistyczne Code::Blocks. Całość kodu składa się z 1000 linii kodu. Napisanie aplikacji zajęło mi około 20 roboczogodzin. Przyznam, że była to dobra zabawa : ) Aplikację można pobrać stąd: http://www.filefront.com/14901641/Tlen-Prowokator-v0.1.rar/ Jeśli z jakichś przyczyn nie mozliwe jest pobranie aplikacji zawsze możesz napisać do mnie e-mail, podałem go na stronie  „O mnie”.

 

EDIT do tego wpisu : W programie był drobny błąd. Mianowicie po zalogowaniu a następnie wylogowaniu przycisk `Zaloguj` nie zmieniał swojej nazwy w związku z czym mogło to niektórych wprowadzać w błąd. Umieszczam wersję poprawioną 😉 http://www.filefront.com/14905753/Tlen-Prowokator-v0.1b.rar/

Na tej stronie możesz oceniać ten projekt  http://answers.polldaddy.com/poll/2250305/

1 października 2009

Nowy projekt…

Filed under: C++,Programowanie,Projekty — winuser @ 18:29

A więc zdecydowałem się na rozpoczęcie nowego projektu. Język to oczywiście C++ a sam projekt.. cóż nazwijmy to Skryptowy System Instalacyjny. Zawsze kiedy tworzyłem jakieś aplikacje potrzebowałem oprogramowania do tworzenia instalatorów – a te z kolei było albo bardzo drogie albo skomplikowane. Dlatego postanowiłem stworzyć coś kompromisowego o podstawowych możliwościach i prostej składni. Projekt składałby się z dwóch albo i trzech głównych modułów pisanych w miare równolegle. Pierwszy moduł – edytor tekstowy dla skryptów + generator EXE i kompresor (RAR lub ZIP jeszcze nie zdecydowane). Moduł pisany jest z użyciem biblioteki VCL Borlanda ze względu na prostotę budowania GUI i małe znaczenie wydajności oraz rozmiaru końcowego. Drugi moduł to baza dla instalatora – moduł SFX. Ponieważ musi być mozliwie małego rozmiaru zdecydowałem się na wykorzystanie nieco archaicznego już kompilatora Microsoft Visual C++ 6.0 potrafi on wygenerować pliki wykonywalne rozmiaru 25 kb, sądze że finalnie będzie zajmował około 50 kb po kompresji UPX`em. Moduł ten będzie pisany z użyciem Windows API. Ostatni, trzeci moduł to klasa parsera języka SSI. Będzie pisana zgodnie ze standardem C++ i wykorzystywać biblioteke STL. Klasa ta będzie używana w obydwóch modułach wykonywalnych. Na razie zamieszczam pare zrzutów częściowo wykonanego GUI edytora oraz instalatora.

Skryptowy System Instalacyjny - moduł SFX
Skryptowy System Instalacyjny - edytor