[英]Hash::Ordered versus Tie::IxHash with JSON::XS encode
I'm trying Hash::Ordered
instead of Tie::IxHash
, because it seems to be faster. 我正在尝试Hash::Ordered
而不是Tie::IxHash
,因为它似乎更快。
While Tie::IxHash
is working fine, I struggle with some problems with Hash::Ordered
. 虽然Tie::IxHash
工作正常,但我遇到了Hash::Ordered
一些问题。 The point is to have the hashes ordered (which are usually random in Perl). 关键是要对哈希值进行排序(在Perl中通常是随机的)。
use Hash::Ordered;
use JSON::XS;
use Data::Dumper;
use strict;
use warnings;
my $json = JSON::XS->new;
my $oh = Hash::Ordered->new;
$oh->push('result' => { 'counter' => "123" }, 'number' => { 'num' => '55' });
my @r = $oh->as_list;
$json->pretty(1);
my $jsondata = $json->encode(\@r);
print Dumper $jsondata;
The result is odd: 结果很奇怪:
[
"result",
{
"counter" : "123"
},
"number",
{
"num" : "55"
}
]
Here is the working example with Tie::IxHash
, I try to get the same results with Hash::Ordered
. 这是Tie::IxHash
的工作示例,我尝试使用Hash::Ordered
获得相同的结果。
use Data::Dumper;
use Tie::IxHash;
use JSON::XS;
use strict;
use warnings;
my $json = JSON::XS->new;
my %h;
tie(%h, 'Tie::IxHash', result => { counter => "123" }, number => { num => '55' });
$json->pretty(1);
my $pretty_json = $json->encode(\%h);
print Dumper $pretty_json;
Output 产量
{
"result" : {
"counter" : "123"
},
"number" : {
"num" : "55"
}
}
The object-oriented interface of Hash::Ordered
is much faster that the tied interface, but some utilities (like $json->encode
) require a real hash reference Hash::Ordered
的面向对象接口比绑定接口快得多,但是一些实用程序(如$json->encode
)需要一个真正的哈希引用
The way to get the best of both worlds is to tie a hash for use with those utilities, and use tied
to extract the underlying Hash::Ordered
object so that you can use the faster method calls to manipulate it 获得两全其美的方法是将哈希与这些实用程序结合使用,并使用tied
来提取底层的Hash::Ordered
对象,以便您可以使用更快的方法调用来操作它
This short program demonstrates. 这个简短的程序证明了 The only slow part of this code is when the hash is passed to encode
to be translated to JSON. 此代码中唯一缓慢的部分是将哈希传递给encode
以转换为JSON。 The push
call doesn't use the tied interface and remains fast push
调用不使用绑定接口并保持快速
use strict;
use warnings;
use Hash::Ordered;
use JSON::XS;
my $json = JSON::XS->new->pretty;
tie my %h, 'Hash::Ordered';
my $oh = tied %h;
$oh->push( result => { counter => 123 }, number => { num => 55 } );
print $json->encode(\%h), "\n";
{
"result" : {
"counter" : 123
},
"number" : {
"num" : 55
}
}
Use the Hash::Ordered tied interface : 使用Hash :: Ordered绑定接口 :
my $json = JSON::XS->new;
tie my %hash, "Hash::Ordered";
$hash{'result'} = { 'counter' => "123" };
$hash{'number1'} = { 'num' => '1' };
$hash{'number2'} = { 'num' => '2' };
$hash{'number3'} = { 'num' => '3' };
$hash{'last'} = { 'num' => 'last' };
$json->pretty(1);
my $jsondata = $json->encode(\%hash);
And the JSON data you get is: 你得到的JSON数据是:
{
"result" : {
"counter" : "123"
},
"number1" : {
"num" : "1"
},
"number2" : {
"num" : "2"
},
"number3" : {
"num" : "3"
},
"last" : {
"num" : "last"
}
}
The examples above work fine, but for multidimensional hashes there is an additional step needed to keep the order. 上面的示例工作正常,但对于多维哈希,还需要一个额外的步骤来保持顺序。
use Hash::Ordered;
use JSON::XS;
use Data::Dumper;
use strict;
use warnings;
sub ordered_hash_ref {
tie my %hash, 'Hash::Ordered';
my $oh = tied %hash;
$oh->push(@_);
return \%hash;
};
my $json = JSON::XS->new->pretty;
tie my %h, 'Hash::Ordered';
my $oh = tied %h;
$oh->push(result => ordered_hash_ref(counter => 123, z => 5, s => 8), address => ordered_hash_ref(Vorname => 'Max',
Nachname => 'Mustermann', Strasse => 'Feldweg', Hausnummer => 45));
my $pretty = $json->encode(\%h);
print Dumper $pretty;
Output 产量
{
"result" : {
"counter" : 123,
"z" : 5,
"s" : 8
},
"address" : {
"Vorname" : "Max",
"Nachname" : "Mustermann",
"Strasse" : "Feldweg",
"Hausnummer" : 45
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.