Как ускорить такой PHP скрипт?

T
На сайте с 28.06.2007
Offline
82
1305

Есть база в виде текстового файла baza.txt, в ней содержится около 2млн. строк, а именно URL вида:

http://yandex.ru/19789

http://yandex.ru/278978
http://yandex.ru/3789
http://yandex.ru/487978
http://yandex.ru/5987987
http://google.ru/1789
http://rambler.ru/187987
http://mail.ru/19879
http://google.ru/2789
http://google.ru/3789
http://google.ru/487979
http://google.ru/57789
http://google.ru/69879
http://google.ru/77789
http://mail.ru/2789
http://mail.ru/379
http://mail.ru/479789
http://mail.ru/578978
http://rambler.ru/29789
http://rambler.ru/387987

Нужно сделать так, чтобы скрипт оставлял в текстовом файле URL до тех пор, пока его хост не повторится 4 раза, т.е. первый второй третий четвётрый URL записываем с одним и темже хостом, а 5, 6, 7 и тд. URL с повторяющимся Хост записывать не нужно

В результате должно получится:

http://yandex.ru/19789

http://yandex.ru/278978
http://yandex.ru/3789
http://yandex.ru/487978
http://google.ru/1789
http://rambler.ru/187987
http://mail.ru/19879
http://google.ru/2789
http://google.ru/3789
http://google.ru/487979
http://mail.ru/2789
http://mail.ru/379
http://mail.ru/479789
http://rambler.ru/29789
http://rambler.ru/387987

Я как только уже не писал, но скорость никакая :( база очень большая 2млн записей, обрабатывает очень медленно.

Вот как писал, через foreach тоже пробовал, маленькая база обрабатывается, а на большой спотыкается и зависает:

<?php

set_time_limit(0);
$list = file("baza.txt"); //База URL
$host="";
for ($i=0; $i<count($list); $i++)
{
$str=trim($list[$i]);
$domens=parse_url($str);
$domen=$domens["host"];

if(substr_count($host, $domen)<4)
{
$host.=$str."
";
}
}
file_put_contents("host.txt", $host);
?>

Помогите ускорить скрипт пожалуйста.

F
На сайте с 24.04.2009
Offline
45
#1
Trol:

Вот как писал, через foreach тоже пробовал, маленькая база обрабатывается, а на большой спотыкается и зависает:
<?php

set_time_limit(0);
$list = file("baza.txt"); //База URL
$host="";
for ($i=0; $i<count($list); $i++)
{
$str=trim($list[$i]);
$domens=parse_url($str);
$domen=$domens["host"];

if(substr_count($host, $domen)<4)
{
$host.=$str."
";
}
}
file_put_contents("host.txt", $host);
?>


Помогите ускорить скрипт пожалуйста.

Лехко, озвучиваете нормальную цену, и желающих ускорить сей говнокод набежит хоть пруд пруди.

[Удален]
#2

А mysql использовать вместо текстового файла не вариант ? Работать будет гораздо быстрее...

T
На сайте с 28.06.2007
Offline
82
#3

Вот чуть изменил код, больше не вижу как оптимизировать ещё можно, медленно очень работает :(

Fearful, такой код можно ещё лучше оптимизировать?

Вот:

<?php

set_time_limit(0);
$list = file('baza.txt'); //База URL
$host = $url = '';
foreach($list as $val) {
$uri = parse_url($val, PHP_URL_HOST)."\n";
if(substr_count($host, $uri)<4) {
$url .= $val;
$host .= $uri;
}
}
file_put_contents('link.txt', $url);
?>

GizmoKoenig, mysql не вариант :(

[Удален]
#4
Trol:
Вот чуть изменил код, больше не вижу как оптимизировать ещё можно, медленно очень работает :(
Fearful, такой код можно ещё лучше оптимизировать?
Вот:
<?php

set_time_limit(0);
$list = file('baza.txt'); //База URL
$host = $url = '';
foreach($list as $val) {
$uri = parse_url($val, PHP_URL_HOST)."\n";
if(substr_count($host, $uri)<4) {
$url .= $val;
$host .= $uri;
}
}
file_put_contents('link.txt', $url);
?>


GizmoKoenig, mysql не вариант :(

так попробуй

set_time_limit(0);


$fp = fopen('baza.txt', 'r');
$fp2 = fopen('host.txt', 'w');

while(!feof($fp)) {
$string=fgets($fp, 1024);
$uri = parse_url( $string, PHP_URL_HOST);
$arr[$uri]++;
if($arr[$uri] <= 4) {
fputs($fp2, $uri . "\r\n");
}
}
fclose($fp);
fclose($fp2);
Dreammaker
На сайте с 20.04.2006
Offline
570
#5
Trol:
mysql не вариант

религия не позволяет?

Joker-jar
На сайте с 26.08.2010
Offline
154
#6

<?php 

set_time_limit(0);
$list = file("baza.txt"); //База URL

sort($list);
$res_list = "";

$prev_host = '-1';
$cur_count = 1;

foreach ($list as $str)
{
$str = trim($str);

preg_match('/http:\/\/[a-z0-9-_\.]+/i', $str, $cur_host);
if ( strcmp($prev_host, $cur_host[0]) == 0 )
{
if ( $cur_count > 3 ) continue;
$cur_count++;
$res_list .= $str . "\n";
}
else
{
$cur_count = 1;
$prev_host = $cur_host[0];
$res_list .= $str . "\n";
}
}

file_put_contents("host.txt", $res_list);
?>

Joker-jar добавил 25.08.2011 в 03:36

Вот так еще оптимизированнее:

<?php 

set_time_limit(0);
$list = file("baza.txt"); //База URL

sort($list);
$res_list = "";

$prev_host = '-1';
$cur_count = 1;

foreach ($list as $str)
{
$str = trim($str);

if ( strpos($str, $prev_host) === 0 )
{
if ( $cur_count > 3 ) continue;
$cur_count++;
$res_list .= $str . "\n";
}
else
{
$cur_count = 1;
preg_match('/http:\/\/[a-z0-9-_\.]+/i', $str, $cur_host);
$prev_host = $cur_host[0];
$res_list .= $str . "\n";
}
}

file_put_contents("host.txt", $res_list);
?>

но надо потестить, я не пробовал :)

O
На сайте с 15.10.2009
Offline
43
#7
GizmoKoenig:
А mysql использовать вместо текстового файла не вариант ? Работать будет гораздо быстрее...

А если MariaDB использовать, то еще быстрее будет.

Программирую на python !!!
T
На сайте с 28.06.2007
Offline
82
#8

Dreammaker, тогда придётся импортировать текстовый файл 300мб-2Гб в базу, что неудобно.

GizmoKoenig, спасибо огромное, работает быстрее.

Joker-jar, огромное спасибо за помощь, тоже работает быстро, базу в 2 миллиона обрабатывает за минуту :)

Спасибо всем за помощь!

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий