|
|
ru.perl- RU.PERL ---------------------------------------------------------------------- From : Sergey Skvortsov 2:5020/400 03 Jul 2003 17:11:21 To : Yury Kopyl Subject : Re: использование join -------------------------------------------------------------------------------- YK> i>> Hi all !! Есть строчка типа print join("','",@ips) - печатает все YK> i>> элементы массива @ips в строчку разделяя , Задача такова: можно ли YK> i>> из массива @ips выбирать не все строчки а по шаблону соотв не YK> i>> прибегая к циклам ? те реализовать вот это в одной строчке : $k=''; YK> i>> foreach my $element(@ips) { if ($element=~/^[0-9]{1,20}$/) { YK> i>> $k.=",".$element; YK> i>> } YK> i>> } явная ошибка в коде. будет строка типа ",1,2,3" вместо ожидаемой "1,2,3". оно тебе точно надо? :) AM>> Во-первых, лучше это делать всё же в цикле. При всём моём уважении AM>> к шворциан-трансформам, сопровождать такой код малоприятное занятие. интересно, а каким боком здесь ST? sort никак на задействуются - зачем эти страшные слова? насчет цикла - спорно. например map в общем случае быстрее foreach. насчет сопровождать - map это более perl-way, чем foreach. так можно сказать, что "action if cond;" удобнее сопровождать, чем "if(cond) {action}". не факт. зависит от степени погруженности в perl. AM>> Во-вторых, можно использовать функцию grep. YK> print join("','",grep( /^[0-9]{1,20}$/ ,@ips)) - чего здесь непонятного? непонятно нафига "','" - подразумевалось ','? YK> imho наоборот - луше видно логику преобразований, чем разворачивать это в YK> цикл. 1. цикл уже написан. если это runaway скрипт - нефиг заморачиваться, и оставить как есть (laziness, знаете ли) 2. если исходить из условий задачи, то join тут как бы вообще не в тему. как бы эффективнее сразу печатать - при join выделяется новый scalar, в который все сливается, который печатается и более не используется. при достаточно большом как размере @ips, так и длине его элементов - может быть значительный memory overhead. (тут еще конечно вопрос - куда печатаем - в файл или сокет, но это уже нюансы. равно как и если @ips есть tied - то вопрос о скорости разрешит только Benchmark). однако есть одно "но": join и map - не вполне функции, а операторы, и жутко оптимизированы. вот тестовый скрипт: #!/usr/bin/perl use strict; use Benchmark; our @vals=0..999; timethese(10000,{ 'for-fast' => sub { my $el; for $el (@vals[0..$#vals-1]) { if($el%2) { print $el,','; }#if }#for $el=$vals[$#vals]; print $el if $el%2; }, 'for-c-way' => sub { my $el; my $size=$#vals; for(my $i=0; $i<=$size; $i++) { $el=$vals[$i]; if($el%2) { print $el; print ',' unless $i==$size; }#if }#for }, 'join' => sub { my $k=join(',', grep({$_%2} @vals)); print $k; }, }); а вот результаты (freebsd 4.8, perl 5.8.0, P4 2.40GHz): for-c-way: 17 wallclock secs (16.70 usr + 0.03 sys = 16.73 CPU) @ 597.57/s (n=10000) for-fast: 13 wallclock secs (12.91 usr + 0.05 sys = 12.96 CPU) @ 771.55/s (n=10000) join: 4 wallclock secs ( 3.55 usr + 0.04 sys = 3.59 CPU) @ 2788.67/s (n=10000) аналогичный тест не с print, а с $k.= - выдает опять же преимущество join+grep. короче, join map/grep безусловно рулят. -- Sergey Skvorstov mailto: skv@protey.ru Отправлено через сервер Форумы@mail.ru - http://talk.mail.ru --- ifmail v.2.15dev5 * Origin: Talk.ru (2:5020/400) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.perl/64883098b032.html, оценка из 5, голосов 10
|