Форум успешных вебмастеров - GoFuckBiz.com

  Форум успешных вебмастеров - GoFuckBiz.com > Бизнес-решения > Скрипты, программы и технические решения
Дата
USD/RUB59.1160
BTC/USD0.0000
Скрипты, программы и технические решения Обсуждаем скрипты, программы и новые технологии.

Закрытая тема
Опции темы Опции просмотра
Старый 17.01.2010, 15:05   #1
Dux
Senior Member
 
Аватар для Dux
 
Регистрация: 29.09.2009
Сообщений: 412
Бабло: $93270
По умолчанию Подскажите, можно ли оптимизировать этот скрипт?

В файле test.txt содеждатся записи вида:
Код:
27	123.156.246.4
12	10.456.45.41
2	32.16.48.84
1	222.4.46.9
в одном файле обычно не более 3000 записей.
каждый раз этот файл дергается и в него добавляется запись, если IP уже есть, то делается плюс к первому столбцу, если нет, то новая строка.
базу использовать нельзя, поэтому только файлы.

вот пример скрипта, подскажите, можно ли как то его оптимизировать?
PHP код:
<?
$file
=file("test.txt");
$new_ip="123.123.123.123";
 
foreach (
$file as $IPs) {
    list(
$count,$ip)=split("[\t]"$IPs);
    
$count=trim($count);
    
$ip=trim($ip);
    
$a[$ip]=$count;
 }
@
$a[$new_ip]++;

$for_write='';
foreach (
$a as $ip=>$count){
    
$for_write.=$count."\t".$ip."\n";
}
 
$fp=fopen("test.txt","w+");
    
fwrite($fp,$for_write);
    
fclose($fp);
?>
P.S. ну точнее мне надо его ускорить
Dux вне форума  
Старый 17.01.2010, 16:22   #2
dveredel
Читатель
 
Аватар для dveredel
 
Регистрация: 23.11.2007
Сообщений: 423
Бабло: $48745
По умолчанию

Если записей действительно немного, как ты сказал, то особо и не ускоришь, поскольку то что можно сделать даст видимый результат только при большом объеме информации.

А с учетом мелкого файла лично я бы практически тоже самое написал, но покороче
PHP код:
$file file("test.txt"FILE_IGNORE_NEW_LINES FILE_SKIP_EMPTY_LINES); // trim and skip
$new_ip "123.123.123.123";

// здесь бы я не стал проходить по всему массиву, нам же одна строчка нужна
foreach ($file as $i => &$str) {
    list(
$count,$ip) = explode("\t"$str);  //регулярок тут не надо 
    
if($ip == $new_ip) {      // валим отседова
        
$str = (++$count)."\t".$ip;   // пишем новую строку сразу в массив
        
break;
    }
}
// если айпи не найден
if($i >= count($file)) {
        
$file[] = "1\t".$new_ip;
}

// и не нужен дополнительный проход по массиву

file_put_contents("test.txt"implode("\r\n"$file)); 
Если же айпишек много, то я бы разбил на кучу файликов по первой цифре айпи...

Если айпишек немного но заходят часто (т.е просмотров на один айпи много), то я бы отсортировал массив перед записью и искал бы уже не перебором а с помощью "алгоритма поиска в упорядоченном массиве".

Ну а если совсем "ппц тдска и лям трафа", то и в массив не стал бы загружать целиком а дергал по строке из файла в сочетании с кучей файлов дабы не уронить скрипт, хотя в этом случае без базы лучше не делать вобще.
dveredel вне форума  
Старый 17.01.2010, 16:37   #3
Dux
Senior Member
 
Аватар для Dux
 
Регистрация: 29.09.2009
Сообщений: 412
Бабло: $93270
ТС -->
автор темы ТС По умолчанию

спасибо, попробую.
ну самих файлов после последнего запуска получилось около 80к.
раскидываются на 40 папок, не по "первой цифре", по другому признаку.
Dux вне форума  
Старый 15.02.2010, 02:52   #4
vilnus
Member
 
Регистрация: 12.02.2010
Сообщений: 41
Бабло: $7055
По умолчанию

А тебе чтение из этого файла надо ускорить, или запись?
Я так понимаю это что-то типа лога. Если читаешь из файла не так часто, то сделай просто
PHP код:
$fp fopen('logs.txt','a');
fwrite($fp"1\t$new_ip\r\n");
fclose($fp); 
Не перезаписывает весь файл. Поддерживает буфферизацию на уровне ФС (отложенные записи там..). Реально работает быстро.

А при чтении этого всего делай array_count_values() и получай что там тебе надо.

Файл, ессно, будет распухать со временем до неприличных размеров. Его периодически можно "сжимать" до описанного тобой формата (т.е. суммировать значения из первого столбца для одинаковых ip). Но делать это можно по крону.
vilnus вне форума  
Старый 15.02.2010, 12:46   #5
Dux
Senior Member
 
Аватар для Dux
 
Регистрация: 29.09.2009
Сообщений: 412
Бабло: $93270
ТС -->
автор темы ТС По умолчанию

я уже все в оператику загнал
Dux вне форума  
Старый 15.02.2010, 12:51   #6
greenwar
Ебланнед
 
Регистрация: 07.02.2010
Сообщений: 1,053
Бабло: $119555
По умолчанию

быстрее всего создавать отдельный файл на каждый IP (filename="123.123.123.123") и в него кидать дозаписью доп.строку или символ = посещение

P.S. локи не забудь
greenwar вне форума  
Старый 15.02.2010, 13:12   #7
Dux
Senior Member
 
Аватар для Dux
 
Регистрация: 29.09.2009
Сообщений: 412
Бабло: $93270
ТС -->
автор темы ТС По умолчанию

Цитата:
Сообщение от greenwar Посмотреть сообщение
быстрее всего создавать отдельный файл на каждый IP (filename="123.123.123.123") и в него кидать дозаписью доп.строку или символ = посещение

P.S. локи не забудь
поверь мне, быстрей всего - это массив в памяти.
у меня после 100k файлов скрипт начинал подтормаживать.

а массив и с 200к элементами работает прекрасно.
Dux вне форума  
Старый 15.02.2010, 13:31   #8
ar4ibas
Senior Member
 
Регистрация: 11.11.2009
Сообщений: 362
Бабло: $71310
По умолчанию

в данном случае узкое место это то что каждый раз при запуске скриптафайл открывается и парсится, в цикле заполняется массив. В идеале конечно лучше всего было бы использовать key-value базу данных типа мемкеша. Но раз использовать бд нельзя то я бы тебе посоветовал чисто для експеримента попробовать так:
- создать массив типа $count[$ip]
- зделать ему serialize и записать в файл
- читать файл и делать ему unserialize врезультате получая массив
- изменять значение $count[$ip]++;

также можно посмотреть в сорону json здесь http://habrahabr.ru/blogs/php/30234/
ar4ibas вне форума  
Старый 15.02.2010, 13:31   #9
greenwar
Ебланнед
 
Регистрация: 07.02.2010
Сообщений: 1,053
Бабло: $119555
По умолчанию

Цитата:
Сообщение от Dux Посмотреть сообщение
поверь мне, быстрей всего - это массив в памяти.
у меня после 100k файлов скрипт начинал подтормаживать.

а массив и с 200к элементами работает прекрасно.
какой памяти? разговор был про файловый вариант изначально (цитата:базу использовать нельзя, поэтому только файлы)
или уже мускуль подключили?
greenwar вне форума  
Старый 15.02.2010, 13:50   #10
Dux
Senior Member
 
Аватар для Dux
 
Регистрация: 29.09.2009
Сообщений: 412
Бабло: $93270
ТС -->
автор темы ТС По умолчанию

Цитата:
Сообщение от ar4ibas Посмотреть сообщение
- создать массив типа $count[$ip]
- зделать ему serialize и записать в файл
- читать файл и делать ему unserialize врезультате получая массив
- изменять значение $count[$ip]++;
именно так и сделал
только serialize делаю каждую тысячу, но массив отсается в памяти.
unserialize делается только при запуске скрипта.

Цитата:
Сообщение от greenwar Посмотреть сообщение
какой памяти? разговор был про файловый вариант изначально (цитата:базу использовать нельзя, поэтому только файлы)
или уже мускуль подключили?
файлы были изначально. но когда в папках оказывалось больше пару тысяч файлов, начинались тормоза. пришлось отказаться
Dux вне форума  
Закрытая тема



Опции темы
Опции просмотра