Forum Webscript.Ru
Программирование => Perl => Тема начата: 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++;
}
может я вообще перехимичил?
-
Визуально первый предпочтительнее, хотябы только потому что не идет считывание всего фала в лишний массив.
perldoc Benchmark
-
($id,$_,$_,$_,$_)=split(/\\|/);
Это новый стиль программирования на перл? Я имею в виду использование магической $_?
-
2NetFly:
Это новый стиль программирования на перл? Я имею в виду использование магической $_?
это что б е забивать голову вам и было наглядней :)
-
Перлдок не рекомендует явное присваивание магическим переменным, особенно $_. Это может стать причиной сложно обнаруживаемых ошибок.
-
2NetFly:
Перлдок не рекомендует явное присваивание магическим переменным, особенно $_. Это может стать причиной сложно обнаруживаемых ошибок.
я же говорю, это я для вас сделал :)
кстати, раз уж тут поднялся этот вопрос. а что есть альтернатива $_ ?
вопрос о скорости и вариантах остается открытым.
-
Что значит альтернатива?
А касательно скорости NeoNox уже ответил. Первый вариант правильнее, т.к. ты работаешь только с текущей строкой файла. Считывать в массив весь файл - это лишние, в данном случае ненужные, телодвижения.
-
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]; - самый быстрый вариант
-
2NetFly:
А касательно скорости NeoNox уже ответил.
вопрос спорный, т.к. в первом случае идет проверка для каждой строки
if ($id>$idold)
и при этом все равно перебирается весь массив
-
Green Kakadu:
во втором примере (правда не меняет \'|\' на запятую - может просто сразу в файл писать разделитель запятую)
my @spisok = map {s/^\\d+?\\|//&&$_} @list[$idnew..$#list];
немножко не то...
мне потом этот @spisok разделить надо будет на ($id,$_,$_,$_,$_)=(номер, дата, от кого, кому, сообщение)
-
($id,undef,undef,undef,undef)=split(/\\|/, $list[0]);
Эм, а undef зачем? =)
($id) = split(/\\|/, $list[0]);
или так
$id = (split /\\|/, $list[0])[0];
А вообще, я что-то с трудом понимаю, что делает код, описанный в перовом посте. Особенно, то место, где в @spisok добавляется много-много $_ ;=)
-
Если ты хочешь, чтоб тебе помогли, опиши рабочий код, а не специально "для нас" испорченный. Ну не будет у тебя работать конструкция:
($id,$_,$_,$_,$_)=(номер, дата, от кого, кому, сообщение)
В данном случае, в $_ окажется сообщение, а push (@spisok,"$_,$_,$_,$_") добавит в список не то, что ты хотел.
-
Yaroslav:
мне потом этот @spisok разделить надо будет на ($id,$_,$_,$_,$_)=(номер, дата, от кого, кому, сообщение)
ээ, так в каком формате должна быть строка в @spisok с id или без него?
если вопрос в том чтоб из "|" сделать ","
то
my @spisok =map {tr/\\|/,/&&$_} @list[$idnew..$#list];
-
2NetFly:
Если ты хочешь, чтоб тебе помогли, опиши рабочий код, а не специально "для нас" испорченный.
это наверное чтоб мы гениальный замысел программы не прознали
-
Yaroslav:
но запрос на его вызов будет 30 раз в сек.
нехилая частота. а как часто он будет обновляться?
может имеет смысл убрать flock?
-
2NetFly
Green Kakadu
исправил по требованию трудящихся исходный код. :)
-
Если операция чтения будет производиться _гораздо_ чаще операции записи, можно писать в начало файла, а не в конец. Тогда можно будет читать построчно только нужное количество строк. Хотя, если в файле будет 30 строк, не думаю, что чтение лишних 20 существенно скажется на производительности. Впрочем, возьми да проверь.
-
Green Kakadu:
может имеет смысл убрать flock?
Что бы гарантировано записи пошли лесом?
-
2NetFly:
Если операция чтения будет производиться _гораздо_ чаще операции записи, можно писать в начало файла, а не в конец
1. тогда будет сложнее записывать в файл
2. сейчас когда я добрался к выводу из файла, нашел нужную строчку и пошел читать (как в первом варианте), а так нужно будет в масив загонять.
-
Я вот не пойму, у тебя файл отсортирован по id? Описанный мной вариант решение предполагает, что да.
-
2NetFly:
Я вот не пойму, у тебя файл отсортирован по id? Описанный мной вариант решение предполагает, что да.
да!
при добавлении в него увеличивается на id на 1 :)
-
Тогда, объясняю в чем разница. Если ты пишешь в конец файла, для того, чтоб вывести записи, чей id больше заданного, тебе, если не считывать во временный массив, необходимо гарантированно прочесть все строки файла. Здесь ты можешь сэкономить разве что на условном выражении: после нахождения первой строки, удовлетворяющей условию, тебе не нужно делать проверку всех оставшихся т.к. заведомо известно, что все они имеют id больше заданного.
Если ты пишешь новые строки в начало файла, то тебе нужно будет считать ровно столько строк, сколько тебе нужно. Т.е. ты считываешь строки до тех пор, пока не встретишь строку, id которой _меньше_ заданного. Время записи в файл действительно увеличивается, поэтому, как я уже писал выше, данный метод имеет смысл использовать только в том случае, если ты читаешь файл _намного_ чаще, чем пишешь в него.
-
2NetFly
вообще то в чате всегда больше читают чем пишут :))
но у меня другое волнение, что б он при громозкой записи не мешал читать :)
-
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;