[Moscow.pm] Очень медленное нахождение элемента в массиве

Толян II agrishaev на gmail.com
Пт Ноя 25 04:16:23 PST 2016


У тебя сам цикл тормозит, а не grep
==================================================================================
    use Time::HiRes qw(time);
    use NetAddr::IP;

my @ips = (
        map("172.16.1.".$_, 1..254 ),
        map("172.16.2.".$_, 1..254 ),
        map("172.16.3.".$_, 1..254 ),
        map("172.16.4.".$_, 1..254 ),
);

    for my $i ( 0 .. 4 ) {
        my $iponly = 995 + $i;
        my $s      = time();
        my %ips    = map { $_ => 1 } @ips;
        my $r1     = ( not exists $ips{$iponly} );
        my $time1  = time - $s;

        $s = time();
        my $r2 = grep $_ eq $iponly, @ips;
        my $time2 = time - $s;

        $s = time();
        my $ipn = NetAddr::IP->new("172.16.1.1/16");
        while($ipn < $ipn->broadcast){
            my $iponly = (split "/", $ipn++)[0];
        }

        my $time3 = time - $s;

        printf( "i=$i\tmap=%4.3fms grep=%4.3fms while=%4.3fms\n", $time1 *
1000, $time2 * 1000, $time3 * 1000 );
    }
=================================================================================


i=0     map=0.572ms grep=0.136ms while=1726.824ms
i=1     map=0.407ms grep=0.052ms while=1752.693ms
i=2     map=0.394ms grep=0.048ms while=1701.981ms
i=3     map=0.507ms grep=0.063ms while=1786.335ms
i=4     map=0.823ms grep=0.053ms while=1704.208ms

==================================================================================


А если в @ ips еще overloaded ip, то и 10 секунд легко может быть

В твоем куске не видно как они получаются.



25 ноября 2016 г., 15:10 пользователь Naim Sh via Moscow-pm <
moscow-pm на pm.org> написал:

> Оки, я просто думаю щас затестить не весь модуль NetAddr::IP а его lite
> версию ( хотя как я предполагаю выигрыш будет маленький)  + щас
> переустановил точнее пересобрал его xs стало лучше .
> + надо затестить как она будет с broadcast и subnet-zero сетками пахать .
>
> On 11/25/2016 04:07 PM, zhecka via Moscow-pm wrote:
>
> ну я бы не сказал.
>
> $banned = new Net::Patricia;
> if(!$banned->match_string($banip))
>     {
>          $banned->add_string($banip);
>     }
>
> просто заполняешь базу Patricia когда тебе нужно и матчишь что есть и чего
> нет.
>
>
>
> On 25.11.2016 14:54, Naim Sh via Moscow-pm wrote:
>
> да кроме 2 и 3  его нету .
> Кстати как я понял Net::Patricia не очень мне подходит(удобен) ведь мне
> надо найти адрес которого нет в массиве
>
> This module uses a Patricia Trie data structure to quickly perform IP
> address prefix matching for applications such as IP subnet, network or
> routing table lookups ?
>
> On 11/25/2016 03:50 PM, Толян II via Moscow-pm wrote:
>
> У тебя может быть overload в нескольких местах:
> 1) В массиве @ips
> 2)  while( $ipn < $ipn->broadcast )              --- вызов метода +
> overload
> 3) my $iponly = (split '/', $ipn++)[0]; #get     --- overload в чистом
> виде + преобразование в строку.
>
>
>
>
> 25 ноября 2016 г., 14:38 пользователь Naim Sh via Moscow-pm <
> <moscow-pm на pm.org>moscow-pm на pm.org> написал:
>
>> Оки и какой вариант быстрее того же map будет .
>> код имеет такой вид ( точнее его кусок который больше всего времени и ест
>> )
>>
>> массив @ips имеет стандартные ipv4 адреса типа 10.56.6.2, 10.135.8.23  ,
>> 10.135.22.43 и тд и тп .
>>
>>         my $ipn = NetAddr::IP->new("$first_ip/$netmask");
>>
>>         while( $ipn < $ipn->broadcast )
>>         {
>>             my $iponly = (split '/', $ipn++)[0]; #get
>>
>>             if ( ! ( grep {$iponly eq $_}  @ips )  )
>>             {
>>                 return $iponly;
>>             }
>>
>>         }
>>
>> first отдает не то что мне нужно из под этой сети адрес в данном случае
>> 10.135.x.y а 10.56.x.y хотя да он первый пустой, но grep выдает то что
>> нужно.
>>
>> Вроде tie переменных и т.д нету
>>
>>
>>
>> On 11/25/2016 03:29 PM, Sergey Aleynikov via Moscow-pm wrote:
>>
>>> Добрый день,
>>>
>>> map будет быстрее только если поисков по одному и тому же исходному
>>> массиву @ips будет несколько - т.к. операция построения хэша дорогая.
>>> Одноразовый поиск - греп быстрее. first возвращает другое (по смыслу)
>>> значение, чем греп (элемент, а не количество), но логически для этой
>>> задачи разницы быть не должно.
>>>
>>> PS: my %ips; @ips{@ips} = (); быстрее, чем my %ips = map { $_ => 1 }
>>> @ips;
>>>
>>> Best regards,
>>> Sergey Aleynikov
>>>
>>>
>>> 25 ноября 2016 г., 14:00 пользователь Naim Sh via Moscow-pm
>>> <moscow-pm на pm.org> написал:
>>>
>>>> Коллеги, столкнулся с тем что код такого вида , используемый для поиска
>>>> свободных ip v4 адресов на размерах 500-1000 элементов отрабатывается
>>>> под 5
>>>> секунд версия с map :
>>>>
>>>> my %ips = map { $_ => 1 } @ips;
>>>> if (not exists($ips{$iponly} ))
>>>> {
>>>>          return $iponly;
>>>> }
>>>>
>>>>
>>>>   и с grep(sic!) ~2 секунду :
>>>>
>>>> if ( ! ( grep {$iponly eq $_ } @ips ) )
>>>> # spent 27.4ms making 814 calls to NetAddr::IP::Lite::broadcast, avg
>>>> 34µs/call
>>>> # spent 9.56ms making 814 calls to
>>>> NetAddr::IP::Lite::__ANON__[NetAddr/IP/Lite.pm:268], avg 12µs/call
>>>> {
>>>>      return $iponly;
>>>> }
>>>>
>>>> Еще трабла в том что легендарный List::Util отдает быстро но почему не
>>>> тот
>>>> же результат( пробовал first , none ) что и grep?
>>>>
>>>> коллеги это нормально на более-менее среднем сервачке ?
>>>>
>>>>
>>>> --
>>>> Moscow.pm mailing list
>>>> moscow-pm на pm.org | http://moscow.pm.org
>>>>
>>>>
>> --
>>
>> --
>> Moscow.pm mailing list
>> moscow-pm на pm.org | http://moscow.pm.org
>>
>
>
>
>
> --
>
>
>
>
>
>
>
>
> --
>
>
>
> --
> Moscow.pm mailing list
> moscow-pm на pm.org | http://moscow.pm.org
>
>
----------- следущая часть -----------
Вложение в формате HTML было извлечено…
URL: <http://mail.pm.org/pipermail/moscow-pm/attachments/20161125/fd343b20/attachment-0001.html>


Подробная информация о списке рассылки Moscow-pm