Forum Webscript.Ru

Программирование => Perl => Тема начата: Yaroslav от 22 Декабря 2004, 16:01:01

Название: быстрое чтение файла
Отправлено: Yaroslav от 22 Декабря 2004, 16:01:01
какой из вариантов более приемлемый:
скриптик должен открывать файл и искать в нем нужный номер $idold. все остальные сообщения вывести.
Предполагается что в файле будет записей не больше 30, но запрос на его вызов будет 30 раз в сек.

open (LIST,"chat_list.tmp");
flock(LIST, LOCK_SH);
while () {
   ($id,$time,$fromuser,$touser,$mess)=split(/\\|/);
   if ($id>$idold) { print "$id,$time,$fromuser,$touser,$mess\\n"; }
}
close(LIST);


или


open (LIST,"chat_list.tmp");
flock(LIST, LOCK_SH);
@list=;
close(LIST);
($id,$time,$fromuser,$touser,$mess)=split(/\\|/, $list[0]);
if ($id<$idold) { $idnew=$idold-$id; }# высчитали с какой строчки выводить
else { $idnew=0; }
foreach $idnew (@list) {
   ($id,$time,$fromuser,$touser,$mess)=split(/\\|/, $list[$idnew]);
   print "$id,$time,$fromuser,$touser,$mess\\n";
   $idnew++;
}


может я вообще перехимичил?
Название: быстрое чтение файла
Отправлено: NeoNox от 22 Декабря 2004, 16:17:06
Визуально первый предпочтительнее, хотябы только потому что не идет считывание всего фала в лишний массив.
perldoc Benchmark
Название: быстрое чтение файла
Отправлено: 2NetFly от 22 Декабря 2004, 16:41:04
($id,$_,$_,$_,$_)=split(/\\|/);

Это новый стиль программирования на перл? Я имею в виду использование магической $_?
Название: быстрое чтение файла
Отправлено: Yaroslav от 22 Декабря 2004, 16:42:40
Цитировать
2NetFly:
Это новый стиль программирования на перл? Я имею в виду использование магической $_?

это что б е забивать голову вам и было наглядней :)
Название: быстрое чтение файла
Отправлено: 2NetFly от 22 Декабря 2004, 16:53:07
Перлдок не рекомендует явное присваивание магическим переменным, особенно $_. Это может стать причиной сложно обнаруживаемых ошибок.
Название: быстрое чтение файла
Отправлено: Yaroslav от 22 Декабря 2004, 16:59:56
Цитировать
2NetFly:
Перлдок не рекомендует явное присваивание магическим переменным, особенно $_. Это может стать причиной сложно обнаруживаемых ошибок.

я же говорю, это я для вас сделал :)
кстати, раз уж тут поднялся этот вопрос. а что есть альтернатива $_ ?

вопрос о скорости и вариантах остается открытым.
Название: быстрое чтение файла
Отправлено: 2NetFly от 22 Декабря 2004, 17:12:14
Что значит альтернатива?

А касательно скорости NeoNox уже ответил. Первый вариант правильнее, т.к. ты работаешь только с текущей строкой файла. Считывать в массив весь файл - это лишние, в данном случае ненужные, телодвижения.
Название: быстрое чтение файла
Отправлено: Green Kakadu от 22 Декабря 2004, 17:41:12
Цитировать
Yaroslav:
вопрос о скорости и вариантах остается открытым.

во втором примере (правда не меняет \'|\' на запятую - может просто сразу в файл писать разделитель запятую)

open (LIST,"chat_list.tmp");
flock(LIST, LOCK_SH);
@list=;
close(LIST);
($id,undef,undef,undef,undef)=split(/\\|/, $list[0]);
if ($id<$idold) { $idnew=$idold-$id; else { $idnew=0; }
my @spisok = map {s/^\\d+?\\|//&&$_} @list[$idnew..$#list];

ээ :) а если забить на удаление id, то просто выводи
 @list[$idnew..$#list]; - самый быстрый вариант
Название: быстрое чтение файла
Отправлено: Green Kakadu от 22 Декабря 2004, 17:46:39
Цитировать
2NetFly:
А касательно скорости NeoNox уже ответил.

вопрос спорный, т.к. в первом случае идет проверка для каждой строки

 if ($id>$idold)
и при этом все равно перебирается весь массив
Название: быстрое чтение файла
Отправлено: Yaroslav от 22 Декабря 2004, 17:55:10
Цитировать
Green Kakadu:
во втором примере (правда не меняет \'|\' на запятую - может просто сразу в файл писать разделитель запятую)
my @spisok = map {s/^\\d+?\\|//&&$_} @list[$idnew..$#list];

немножко не то...
мне потом этот @spisok разделить надо будет на ($id,$_,$_,$_,$_)=(номер, дата, от кого, кому, сообщение)
Название: быстрое чтение файла
Отправлено: 2NetFly от 22 Декабря 2004, 17:55:15
Цитировать

($id,undef,undef,undef,undef)=split(/\\|/, $list[0]);

Эм, а undef зачем? =)

($id) = split(/\\|/, $list[0]);
или так
$id = (split /\\|/, $list[0])[0];

А вообще, я что-то с трудом понимаю, что делает код, описанный в перовом посте. Особенно, то место, где в @spisok добавляется много-много $_ ;=)
Название: быстрое чтение файла
Отправлено: 2NetFly от 22 Декабря 2004, 18:02:15
Если ты хочешь, чтоб тебе помогли, опиши рабочий код, а не специально "для нас" испорченный. Ну не будет у тебя работать конструкция:
($id,$_,$_,$_,$_)=(номер, дата, от кого, кому, сообщение)
В данном случае, в $_ окажется сообщение, а push (@spisok,"$_,$_,$_,$_") добавит в список не то, что ты хотел.
Название: быстрое чтение файла
Отправлено: Green Kakadu от 22 Декабря 2004, 18:05:03
Цитировать
Yaroslav:
мне потом этот @spisok разделить надо будет на ($id,$_,$_,$_,$_)=(номер, дата, от кого, кому, сообщение)

ээ, так в каком формате должна быть строка в @spisok с id или без него?
если вопрос в том чтоб из "|" сделать ","
то
my @spisok =map {tr/\\|/,/&&$_} @list[$idnew..$#list];
Название: быстрое чтение файла
Отправлено: Green Kakadu от 22 Декабря 2004, 18:06:43
Цитировать
2NetFly:
Если ты хочешь, чтоб тебе помогли, опиши рабочий код, а не специально "для нас" испорченный.

это наверное чтоб мы гениальный замысел программы не прознали
Название: быстрое чтение файла
Отправлено: Green Kakadu от 22 Декабря 2004, 18:11:00
Цитировать
Yaroslav:
но запрос на его вызов будет 30 раз в сек.

нехилая частота. а как часто он будет обновляться?
может имеет смысл убрать flock?
Название: быстрое чтение файла
Отправлено: Yaroslav от 22 Декабря 2004, 18:35:59
2NetFly
Green Kakadu
исправил по требованию трудящихся исходный код. :)
Название: быстрое чтение файла
Отправлено: 2NetFly от 22 Декабря 2004, 18:47:22
Если операция чтения будет производиться _гораздо_ чаще операции записи, можно писать в начало файла, а не в конец. Тогда можно будет читать построчно только нужное количество строк. Хотя, если в файле будет 30 строк, не думаю, что чтение лишних 20 существенно скажется на производительности. Впрочем, возьми да проверь.
Название: быстрое чтение файла
Отправлено: NeoNox от 22 Декабря 2004, 18:49:48
Цитировать
Green Kakadu:
может имеет смысл убрать flock?

Что бы гарантировано записи пошли лесом?
Название: быстрое чтение файла
Отправлено: Yaroslav от 22 Декабря 2004, 18:55:13
Цитировать
2NetFly:
Если операция чтения будет производиться _гораздо_ чаще операции записи, можно писать в начало файла, а не в конец

1. тогда будет сложнее записывать в файл
2. сейчас когда я добрался к выводу из файла, нашел нужную строчку и пошел читать (как в первом варианте), а так нужно будет в масив загонять.
Название: быстрое чтение файла
Отправлено: 2NetFly от 22 Декабря 2004, 19:04:51
Я вот не пойму, у тебя файл отсортирован по id? Описанный мной вариант решение предполагает, что да.
Название: быстрое чтение файла
Отправлено: Yaroslav от 22 Декабря 2004, 19:08:04
Цитировать
2NetFly:
Я вот не пойму, у тебя файл отсортирован по id? Описанный мной вариант решение предполагает, что да.

да!
при добавлении в него увеличивается на id на 1 :)
Название: быстрое чтение файла
Отправлено: 2NetFly от 22 Декабря 2004, 19:15:49
Тогда, объясняю в чем разница. Если ты пишешь в конец файла, для того, чтоб вывести записи, чей id больше заданного, тебе, если не считывать во временный массив, необходимо гарантированно прочесть все строки файла. Здесь ты можешь сэкономить разве что на условном выражении: после нахождения первой строки, удовлетворяющей условию, тебе не нужно делать проверку всех оставшихся т.к. заведомо известно, что все они имеют id больше заданного.

Если ты пишешь новые строки в начало файла, то тебе нужно будет считать ровно столько строк, сколько тебе нужно. Т.е. ты считываешь строки до тех пор, пока не встретишь строку, id которой _меньше_ заданного. Время записи в файл действительно увеличивается, поэтому, как я уже писал выше, данный метод имеет смысл использовать только в том случае, если ты читаешь файл _намного_ чаще, чем пишешь в него.
Название: быстрое чтение файла
Отправлено: Yaroslav от 22 Декабря 2004, 19:31:59
2NetFly
вообще то в чате всегда больше читают чем пишут :))
но у меня другое волнение, что б он при громозкой записи не мешал читать :)
Название: быстрое чтение файла
Отправлено: Yaroslav от 23 Декабря 2004, 02:11:12
2NetFly
родумал еще раз и переделал :)

$oldid - берем из кука
if ($oldid ne "") {
open (LIST,"chat_list.tmp");
flock(LIST, LOCK_SH);
($id,$time,$fromuser,$touser,$mess)=split(/\\|/, ());
if ($oldid<$id) {
chomp($mess);
print "Set-Cookie: mybabyid=$id; path=/; \\n";
&head;
print "$time $fromuser: $touser, $mess
";
while () {
chomp;
($id,$time,$fromuser,$touser,$mess)=split(/\\|/);
if ($oldid<$id) {
print "$time $fromuser: $touser, $mess
";
}
else { last; }
}
}
else { &head; }
}
else { print "Set-Cookie: mybabyid=0; path=/; \\n"; &head; }

&end;