in reply to Re: Why doesn't exist work with hash slices?
in thread Why doesn't exist work with hash slices?

These are even efficient, with 5.42's experimental any and all operators. Before those, I'd almost never use List::Util's any/all/first, unless readability is super important or the body is doing something expensive like I/O, preferring something like:
0 != grep exists $hash{$_}, @keys # any 0 == grep ! exists $hash{$_}, @keys # all

Replies are listed 'Best First'.
Re^3: Why doesn't exist work with hash slices?
by 1nickt (Canon) on Sep 22, 2025 at 10:50 UTC

    While the new functions in core are a lot faster still, at least for any, List::Util has been way faster than grep.

    use strict; use warnings; use v5.42; use feature 'keyword_any'; no warnings 'experimental::keyword_any'; use List::Util; use Benchmark 'cmpthese'; my @list = 0 .. 1_000_000; my %hash = map { $_ => 1 } @list; cmpthese(-5, { 'grep' => sub { return 1 if 0 != grep exists $hash{$_}, @list }, 'List::Util::any' => sub { return 1 if List::Util::any { exists $ +hash{$_} } @list }, 'core any' => sub { return 1 if any { exists $hash{$_} } @list }, });
    Rate grep List::Util::any core any grep 14.1/s -- -98% -99% List::Util::any 634/s 4412% -- -46% core any 1168/s 8209% 84% --


    The way forward always starts with a minimal test.
      When all the keys exist, it's a million iterations against one, so it's not surprising. Use something like
      my %hash; @hash{ map int rand 1_000_000, 1 .. 1000 } = ();
      for a more realistic scenario (still impressive).

      map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
        Still comparing apple and oranges.

        Handrolling your own my_any or exists_any is not that complicated, only 10-15% slower that List::Util:any .

        And exists_any has a nice syntax too.

        sub my_any (&@) { my $block = shift; $block->() && return !!1 for @_ ; return !!0 } sub exists_any (\%@) { my $h_hash = shift @_; exists $h_hash->{$_} && return 1 for @_; return !!0 } my %hash; my @list = 0 .. 1_000_000; @hash{ map int rand @list, 1 .. 1000 } = (); say my_any { exists $hash{$_} } @list; say exists_any %hash, @list; # note cleaner syntax

        Of course there is no point in reinventing my_any if List::Util is available, but if this semanics is regularly needed a custom function will pay of easily in terms of readability.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        see Wikisyntax for the Monastery