简体   繁体   English

Hash :: Ordered与Tie :: IxHash与JSON :: XS编码

[英]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";

output 产量

{
   "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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM