Дополнительное использование поиска хеша 'существует'?

Достаточно забавно, что никто не использует здесь функцию Trim:

public static class StringExtensions
{
    public static bool IsNullOrEmptyOrWhiteSpace(this string value)
    {
        return string.IsNullOrEmpty(value) ||
               ReferenceEquals(value, null) ||
               string.IsNullOrEmpty(value.Trim(' '));
    }
}

Обновление: Я вижу в комментариях, что теперь это было предложено и отклонено по разным причинам, но там оно есть если кто-то предпочитает краткость эффективности ...

5
задан Frank 10 June 2009 в 18:30
поделиться

5 ответов

Проверяя существует , вы предотвращаете автовивификацию. См. Автовивификация: что это такое и почему меня это волнует? .

ОБНОВЛЕНИЕ: Как trendels указывает ниже, автовивификация не применяется в опубликованном вами примере . Я предполагаю, что реальный код включает многоуровневые хэши.

Вот иллюстрация:

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

my (%hash, $x);

if ( exists $hash{test}->{vivify} ) {
    $x = $hash{test}->{vivify}->{now};
}

print Dumper \%hash;

$x = $hash{test}->{vivify}->{now};

print Dumper \%hash;

__END__


C:\Temp> t
$VAR1 = {
    'test' => {}
};
$VAR1 = {
    'test' => {
        'vivify' => {}
    }
};
10
ответ дан 13 December 2019 в 05:41
поделиться

Вы можете использовать lock_keys Hash :: Util к хешу. Затем выполняйте свои назначения в eval.

#!/usr/bin/perl
use Hash::Util qw/lock_keys/;

my %a = (
    1 => 'one',
    2 => 'two'
);

lock_keys(%a);

eval {$val = $a{2}};     # this assignment completes
eval {$val = $a{3}};     # this assignment aborts
print "val=$val\n";      # has value 'two'
1
ответ дан 13 December 2019 в 05:41
поделиться

Вы можете сделать это одним поиском следующим образом:

$tmp = $ids{$name};
$id = $tmp if (defined $tmp);

Однако я бы не стал беспокоиться, если бы не увидел, что это узкое место

1
ответ дан 13 December 2019 в 05:41
поделиться

если это не многоуровневый хэш, вы можете сделать это:

$id = $ids{$name} || 'foo';

или если $ id уже имеет значение:

$id ||= $ids{$name};

, где 'foo' - значение по умолчанию или пропуск стоимость. Если это многоуровневый хеш, вы должны использовать «существует», чтобы избежать автовивификации, обсуждаемой ранее в потоке, или не использовать ее, если автовивификация не будет проблемой.

0
ответ дан 13 December 2019 в 05:41
поделиться

Если мне нужна высокая производительность, я использую эту идиому, когда хочу создать хеш как установленный:

my %h;
for my $key (@some_vals) {
  ...
  $h{$key} = undef unless exists $h{$key};
  ...
}

return keys %h;

Этот код немного быстрее, чем обычно используемый $ h {$ key } ++ . exists избегает бесполезного присвоения, а undef избегает выделения для значения. Лучший ответ для вас: сравните это! Я предполагаю, что существует. $ Ids {$ name} немного быстрее, чем $ id = $ ids {$ name} , и если у вас большой коэффициент промахов, ваша версия с exists может быть быстрее чем назначение и проверка после.

Например, если мне нужно быстрое пересечение множеств, я бы написал что-то вроде этого.

sub intersect {
  my $h;
  @$h{@{shift()}} = ();
  my $i;
  for (@_) {
    return unless %$h;
    $i = {};
    @$i{grep exists $h->{$_}, @$_} = ();
    $h = $i;
  }
  return keys %$h;
}
0
ответ дан 13 December 2019 в 05:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: