The documentation of keys says: "In scalar context, returns the number of keys or indices." Based on this I would say that keys has a shortcut to return the number of keys w/o building an array first. A little experiment seems to confirm this:
use strict;
use warnings;
use Time::HiRes qw/time/;
my %hash;
my $n = 1000000;
@hash{1..$n} = 1 x $n;
my $s = time();
my @k = keys %hash;
print scalar @k, ": ";
print time()-$s, "\n";
$s = time();
print scalar keys %hash, ": ";
print time()-$s, "\n";
The second version is vastly faster.