Perl hash in скалярном contesto

A volte quando si lavora con хешами è possibile vedere qualche strana frazioni.

Ecco un esempio di programma:

#!/usr/bin/perl

my %h = (
    a => 1,
    b => 2,
);

print "hash: " . %h;

Se esegui il programma in versione di Perl 5.22, l'output di questo programma sarà il testo hash: 2/8.

Che cosa è questa frazione?

Quando si utilizza l'operatore punto di hash utilizzato in скалярном contesto. print "hash: " . %h; è lo stesso che e print "hash: " . scalar(%h);

Stringa 2/8 — questo è il risultato di un lavoro di espressione scalar(%h).

Stringa 2/8 racconta la storia di dispositivo interno di hash. Si tratta di statistiche di utilizzo бакетов. È totalmente cucina interna, che molto raramente bisogno. All'interno di hash аллоцируются sezioni speciali sotto il nome di tutti, in cui sono memorizzati i dati. Quello che è scritto a destra della frazione è il numero di аллоцированных бакетов. Il numero a sinistra della frazione è un numero realmente utilizzati бакетов. Quando si aggiunge coppie di valori di hash a un certo punto il numero di аллоцированных бакетов aumenta, per hash lavorato in modo efficace.

Ecco un esempio di un programma che mostra come cambia questi numeri quando si aggiungono i valori di hash:

#!/usr/bin/perl

use feature qw(say);

my %h;

foreach my $i (1 .. 17) {
    $h{$i} = $i;
    say "$i - " . scalar(%h);
}

Ecco l'output di questo programma (si prega di notare che non ogni volta che si aggiunge un valore di hash aumenta il numero dei бакетов):

1 - 1/8
2 - 2/8
3 - 3/8
4 - 3/8
5 - 4/8
6 - 4/8
7 - 4/8
8 - 5/16
9 - 5/16
10 - 6/16
11 - 6/16
12 - 6/16
13 - 6/16
14 - 7/16
15 - 8/16
16 - 12/32
17 - 12/32

È interessante che questi numeri sono impermanenti. Se un paio di volte di eseguire questo script Perl, il prelievo sarà un po ' di variare.

Il cambiamento di lavoro a partire dal Perl 5.26

Statistiche interne hash bisogno solo raramente. Pertanto, a partire dalla versione di Perl 5.26 comportamento hash in скалярном contesto è stato cambiato. Ora hash in скалярном contesto restituisce il numero — il numero di coppie di elementi in хеше. E, francamente, tutti si aspettano di ottenere rivolgendosi a хешу in скалярном contesto.

Prima versione di Perl 5.26 per ottenere il numero di coppie di elementi in хеше c'era bisogno di scrivere scalar(keys(%h));. A partire dalla versione di Perl 5.26 ora questo stesso numero è possibile ottenere con l'aiuto di scalar(%h);.

Ma se qualcuno ha bisogno di ottenere esattamente frazione con le statistiche хешу, allora è possibile farlo con l'aiuto di funzioni bucket_ratio dalla libreria Hash::Util. Ecco un esempio di un programma che sulla versione di Perl 5.26 visualizza il testo hash: 2/8.

#!/usr/bin/perl

use Hash::Util qw(bucket_ratio);

my %h = (
    a => 1,
    b => 2,
);

print "hash: " . bucket_ratio(%h);

Ulteriori statistiche хешу

Se così bisogno di capire cosa sta succedendo con хешом, è possibile utilizzare altri strumenti. A partire dalla versione di Perl 5.22 nella libreria Hash::Util è la funzione bucket_stats_formatted, ecco un esempio il suo utilizzo:

#!/usr/bin/perl

use Hash::Util qw(bucket_stats_formatted);

my %h = (
    a => 1,
    b => 2,
);

print bucket_stats_formatted(\%h);

L'output di questo programma:

Keys: 2 Buckets: 2/8 Quality-Score: 0.94 (Good)
Utilized Buckets: 25.00% Optimal: 25.00% Keys In Collision: 0.00%
Chain Length - mean: 1.00 stddev: 0.00
Buckets              8 [00000011]
Len   0  75.00%      6 [######]
Len   1  25.00%      2 [##]
Keys                 2 [11]
Pos   1 100.00%      2 [##]

Altri articoli