За file_get_contents(); и ускоряване

dakata__92

Super Moderator
Има ли по-бърз начин да се взима информацията на дадена страница в стрингов вид от file_get_contents? Налага ми се да го поставя в цикъл с огромен брой интерациии 900 000 + ако не бъде прекратен при определени условия. Та възможна ли е по бърза функция от тази или да се ускори някак?
 
dakata__92 каза:
Има ли по-бърз нацин да се взима информацията на дадена страница в стренгов вид от file_get_contents? Налага ми се да го поставя в цикъл с огромен брой интерациии 900 000 + ако не бъде прекратен при определени условия. Та възможна ли е по бърза функция от тази или да се ускори някак?
Странно. Пробвах с cURL като си драснах цял метод и излиза по-бързо от file_get_contents. Само аз ли излизам с това заключение и ако да защо е така?!
PHP:
	private function getHtml($url){
		$cookie = tmpfile();
		$userAgent = 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31' ;
		$ch = curl_init($url);
		$options = array(
			CURLOPT_CONNECTTIMEOUT => 20, 
			CURLOPT_USERAGENT => $userAgent,
			CURLOPT_AUTOREFERER => true,
			CURLOPT_FOLLOWLOCATION => true,
			CURLOPT_RETURNTRANSFER => true,
			CURLOPT_COOKIEFILE => $cookie,
			CURLOPT_COOKIEJAR => $cookie,
			CURLOPT_SSL_VERIFYPEER => 0,
			CURLOPT_SSL_VERIFYHOST => 0
		);
		curl_setopt_array($ch, $options);
		$html = curl_exec($ch);
		curl_close($ch);
		return $html;
	}
Викането на този метод е по-бързо от file_get_contents();
 
Опитвам се да ускоря максимално ето този цикъл.
PHP:
for($i=$start;$i<=$end;$i++){
			$doc_reg_number = str_pad($i, $lenEnd, "0", STR_PAD_LEFT);
			if(strpos($this->getHtml($this->URL.$post.$doc_reg_number),'Start file!') !== false){
				return $seria.$doc_reg_number;
			}
		}
 
Давайте идеи как да ускоря нещата. в този цикъл:
PHP:
for($i=$start;$i<=$end;$i++){
$doc_reg_number = str_pad($i, $lenEnd, "0", STR_PAD_LEFT);
if(strpos($this->getHtml($this->URL.$post.$doc_reg_number),'Start file!') !== false){
return $seria.$doc_reg_number;
}
}
// ускорих метода за взимане на html-а така
private function getHtml($url){
		$ch = curl_init($url);
		$options = array(
			CURLOPT_CONNECTTIMEOUT => 0, 
			CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31',
			CURLOPT_REFERER => 'http://google.bg/',
			CURLOPT_RETURNTRANSFER => true,
			CURLOPT_SSL_VERIFYPEER => 0,
			CURLOPT_SSL_VERIFYHOST => 0
		);
		curl_setopt_array($ch, $options);
		$html = curl_exec($ch);
		curl_close($ch);
		return $html;
	}
Важно е да ускоря максимално нещата. Няма как да намаля броя на интерациите защото при всяка се прави проверка. Въпроса е как да сваля времето. При 100 интерации средната скорост е: 21.115207910538
 
lamerko каза:
Досега щеше вече да си дъмпиш данните, вместо да ги мислиш толкова :)
Какво имаш предвид? Данните се обработват по определен начин и постоянно се сменят. Да кажем че с едни данни имам 900 000 интерациии но после с други пак толкова. Съвсем и други неща и така нататък. Мисля го защото се налага да го ускоря. Коефициента средният е 0.3 по броят интерации се получава времето за което ще се изпълнят нещата в секунти.
60 000 * 0,3 = 180 000 секунди
180 000 / 60 = 300 минутки
300 / 60 = 5 часа

Това е твърде много. Дори с половин час да го намаля пак ми е файда.
 
Имай в предвид, че накрая ще те блокират, ако им правиш твърде много трафик. По-добре анализирай какви са промените и дали е възможно да взимаш само тях. Иначе за по-бързо - ами отговора е елементарен... раздели си цикъла на 4 (да кажем) части и го разпределеи на 4 различни скрипта, които ще пуснеш едновременно. Само не се оливай с инстанциите, че ще увеличиш времето, вместо да ги подобриш :)
 
lamerko каза:
Имай в предвид, че накрая ще те блокират, ако им правиш твърде много трафик. По-добре анализирай какви са промените и дали е възможно да взимаш само тях. Иначе за по-бързо - ами отговора е елементарен... раздели си цикъла на 4 (да кажем) части и го разпределеи на 4 различни скрипта, които ще пуснеш едновременно. Само не се оливай с инстанциите, че ще увеличиш времето, вместо да ги подобриш :)
Мммм за инстанцииите не бях се сетил впрочем. Примерно от 1 до 1000 на инстанция 1 на втората инстанция от 1000 до 2000 и тн. Това ли имаш предвид?
 
lamerko каза:
Установих, че номера с инстанциите няма да ми помогне. Реално ще трябва да изчакам едната да провери после следващата защото търся определен ключ. Тоес примерно имам от 00 001 до 60 000 ако веднъж ключът е 3000 то другият път може да е 48 150. Аз ще задам диапазоните на инстанциите но винаги ще ми е нужна логика за да провери дали в даденият на инстанцията диапазон е генериран резултата или не. Ако не е да ходи на диапазон две. Реално погледнато това ще е по-бавното решение поради простата причина, че в момента просто подавам един break; когато генерирам резултата и готово. Няма как да ги накарам двете инстанции да се движат едновременно тоест те връщат резултат все пак от методите си. Просто не е това решението... Тествах пробвах, но единственото за което се сещам е да генерирам две отделни страници по някакъв начин и реално да въртят един и същ цикъл от диапазона +1 и примерно -999 999 тоест веднъж напред и веднъж назад. Как мога да направя това нещо да се движи едновременно?
 
Ускорих го благодарение на cURL. Сетих се да го инициализирам по различен начин и спадна товаренето от 20 секунди на 9 секунди при 100 интерации. 8) 8)
 
Защо не го записваш с Крон джоб в ДБ или във файл и после да го теглиш от там или да си драснеш някакъв вид кеш по нещо?

Или използвай опашки.

На лайф не се правят такива неща.
 
skynet каза:
Защо не го записваш с Крон джоб в ДБ или във файл и после да го теглиш от там или да си драснеш някакъв вид кеш по нещо?

Или използвай опашки.
Това еее твъъъре твърде бавно. Преди малко свалих нещата с около 10 секунди на 100 интерации, коетоооо ме радва много. :?:
 
Аз изобщо се чудя защо като ти трябва такава бързина не ползваш просто друг език.
Ако можеш - защо не пробваш на C(++) примерно? Нещата ще се ускорят със сигурност.

Може би ще отнеме повече време и занимавки, но заради реултата няма ли да си струва?
 
anonimen каза:
Аз изобщо се чудя защо като ти трябва такава бързина не ползваш просто друг език.
Ако можеш - защо не пробваш на C(++) примерно? Нещата ще се ускорят със сигурност.

Може би ще отнеме повече време и занимавки, но заради реултата няма ли да си струва?
Мислил съм, но какъв е смисъслът да пиша и компилирам като откачен кодове, когато реално и с php хващам тази производителност. Незнам функции на C++, които да взимат HTML-а на дадена страница и после спрямо него да правят някакво търсене в стринга. Ако някъде има готов код който да ми връща стринга на подаден url с exex ще се получи супер.
 
Механизма е същия - сваляш контента и прилагаш дадени изрази за парсване. Проблема е, че единственото предисмство е възможността да се използват няколко нишки едновременно, включително и през самия curl (ако решиш да го ползваш въобще). Но реално няма да има някакво видимо подобрение на скоростта, а писането си е доста повече :)
 
lamerko каза:
Механизма е същия - сваляш контента и прилагаш дадени изрази за парсване. Проблема е, че единственото предисмство е възможността да се използват няколко нишки едновременно, включително и през самия curl (ако решиш да го ползваш въобще). Но реално няма да има някакво видимо подобрение на скоростта, а писането си е доста повече :)
Аз реално се сетих да ползвам една сесийна конекция на кърл и само да сетвам линка. Реално е двойно по-бързо от колкото да инициализирам с инит после да затварям и така всеки път. Все пак виках отделен метод връщащ html-а. Ето така е двойно по-бързо.
PHP:
$ch = curl_init();
		$options = array(
            CURLOPT_CONNECTTIMEOUT => 0, 
            CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31',
            CURLOPT_REFERER => 'http://google.bg/',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYPEER => 0,
            CURLOPT_SSL_VERIFYHOST => 0
        );
		curl_setopt_array($ch, $options);
		for($i=$start;$i<=$end;$i++){
			$number = str_pad($i, 6, "0", STR_PAD_LEFT);
			curl_setopt($ch, CURLOPT_URL, $url.$number);
			if(strpos(curl_exec($ch),'html/data/gerb.jpg') !== false){
				return $number;
			}
		}
		curl_close($ch);
Мисля си вече, че това няма как да се ускори повече. :D
 
Е, много ясно, че няма да инициализираш кърл-а на всяка итерация. Иначе за PHP имплементацията няма поддръжка на някои възможности, но не е голяма мъка :)
 
lamerko каза:
Е, много ясно, че няма да инициализираш кърл-а на всяка итерация. Иначе за PHP имплементацията няма поддръжка на някои възможности, но не е голяма мъка :)
Сега ми е ясно ама никой не се усети да ми го каже това и аджеба защо викам отделен метод. Наложи се с доооста ама мнооого мислене да стигна и сам до това заключение. Няма явно вече начин да ускоря нещата.
 
Ако изключа хедърите дали малко ще се ускорят нещата?
curl_setopt($ch, CURLOPT_HEADER, 0);
Като пример го давам?
 

Back
Горе