Perl的2D哈希初始化 – 我们有更快的方法吗?

huangapple go评论96阅读模式
英文:

Perl's 2D hash initialization - do we have any faster way?

问题

I am looking for a fast 2D hash initialization. I know some recommended use undef, but I need it to be 1. I have tested 4 different flavors as below (please ignore the naming, as I am bad at names)
Surprisingly, for_2d_init_array has the fastest execution.

But, i am still not satisfy with it, as when the $limit=4000, it requires roughly 4-5s for complete initialization. Is there any faster way to do so?

I know there is a bit-vector for such application. For now, I would like to maintain such structure.

英文:

I am looking for a fast 2D hash initialization. I know some recommended use undef, but I need it to be 1. I have tested 4 different flavors as below (please ignore the naming, as I am bad at names)
Surprisingly, for_2d_init_array has the fastest execution.

But, i am still not satisfy with it, as when the $limit=4000, it requires roughly 4-5s for complete initialization. Is there any faster way to do so?

I know there is a bit-vector for such application. For now, I would like to maintain such structure.

  1. timethese(-2, {
  2. for_2d_original => sub {
  3. my %hash;
  4. my $limit = 100;
  5. for(my $i=0; $i<$limit; $i++){
  6. for(my $j=0; $j<$limit; $j++){
  7. $hash{$i}{$j}=1;
  8. }
  9. }
  10. },
  11. for_2d_map => sub {
  12. my %hash;
  13. my $limit = 100;
  14. for(my $i=0; $i<$limit; $i++){
  15. $hash{$i} = {map { $_ => 1 } 0..$limit-1};
  16. }
  17. },
  18. for_2d_init_hash => sub {
  19. my %hash;
  20. my $limit = 100;
  21. for(my $i=0; $i<$limit; $i++){
  22. my %tmp_hash;
  23. for(my $j=0; $j<$limit; $j++){
  24. $tmp_hash{$j} = 1;
  25. }
  26. $hash{$i} = \%tmp_hash;
  27. }
  28. },
  29. for_2d_init_hash_w_array => sub {
  30. my %hash;
  31. my $limit = 100;
  32. my @array = (0..$limit-1);
  33. my @init = (1)x$limit;
  34. for(my $i=0; $i<$limit; $i++){
  35. my %tmp_hash;
  36. @tmp_hash{@array} = @init;
  37. $hash{$i} = \%tmp_hash;
  38. }
  39. },
  40. });

Results:
for_2d_original: 3 wallclock secs ( 2.10 usr + 0.00 sys = 2.10 CPU) @ 751.90/s (n=1579)
for_2d_map: 2 wallclock secs ( 2.18 usr + 0.00 sys = 2.18 CPU) @ 559.17/s (n=1219)
for_2d_init_hash: 2 wallclock secs ( 2.15 usr + 0.00 sys = 2.15 CPU) @ 994.42/s (n=2138)
for_2d_init_hash_w_array: 2 wallclock secs ( 2.12 usr + 0.00 sys = 2.12 CPU) @ 1580.19/s (n=3350)

答案1

得分: 1

我从Armali那里得到了一个提示,并用二维数组替换,结果很好。我知道这不再是一个二维哈希,但我认为这个结构很好,因为我只需将{}替换为系统中剩余的遗留代码的[]。谢谢大家。(最初,每行都是不同大小的哈希。)为了完整起见,我包括了代码及其结果。

  1. timethese(-2, {
  2. for_2d_original => sub {
  3. my %hash;
  4. my $limit = 100;
  5. for(my $i=0; $i<$limit; $i++){
  6. for(my $j=0; $j<$limit; $j++){
  7. $hash{$i}{$j}=1;
  8. }
  9. }
  10. },
  11. for_2d_map => sub {
  12. my %hash;
  13. my $limit = 100;
  14. for(my $i=0; $i<$limit; $i++){
  15. $hash{$i} = {map { $_ => 1 } 0..$limit-1};
  16. }
  17. },
  18. for_2d_init_hash => sub {
  19. my %hash;
  20. my $limit = 100;
  21. for(my $i=0; $i<$limit; $i++){
  22. my %tmp_hash;
  23. for(my $j=0; $j<$limit; $j++){
  24. $tmp_hash{$j} = 1;
  25. }
  26. $hash{$i} = \%tmp_hash;
  27. }
  28. },
  29. for_2d_init_hash_w_array => sub {
  30. my %hash;
  31. my $limit = 100;
  32. my @array = (0..$limit-1);
  33. my @init = (1)x$limit;
  34. for(my $i=0; $i<$limit; $i++){
  35. my %tmp_hash;
  36. @tmp_hash{@array} = @init;
  37. $hash{$i} = \%tmp_hash;
  38. }
  39. },
  40. for_2d_init_array => sub {
  41. my $limit = 100;
  42. my @init;
  43. $init[$_] = [(1)x$limit] for 0..$limit-1;
  44. },
  45. });

结果:

  1. for_2d_original: 2秒墙钟时间(2.12秒用户时间+0.00秒系统时间=2.12CPU时间)@744.81/sn=1579
  2. for_2d_map: 2秒墙钟时间(2.19秒用户时间+0.00秒系统时间=2.19CPU时间)@556.62/sn=1219
  3. for_2d_init_hash: 2秒墙钟时间(2.21秒用户时间+0.00秒系统时间=2.21CPU时间)@978.28/sn=2162
  4. for_2d_init_hash_w_array: 2秒墙钟时间(2.15秒用户时间+0.00秒系统时间=2.15CPU时间)@1558.14/sn=3350
  5. for_2d_init_array: 2秒墙钟时间(2.10秒用户时间+0.00秒系统时间=2.10CPU时间)@6018.57/sn=12639
英文:

I took a hint from Armali and replace with 2D array and the results is great. I know this is no longer a 2D hash, I consider this structure as fine, as I can just replace {} to [] for the remaining of the legacy code the system have. Thanks all. (initially, it is a variable sizes of hash in each rows. ) For completeness, I included the code and its results.

  1. timethese(-2, {
  2. for_2d_original =&gt; sub {
  3. my %hash;
  4. my $limit = 100;
  5. for(my $i=0; $i&lt;$limit; $i++){
  6. for(my $j=0; $j&lt;$limit; $j++){
  7. $hash{$i}{$j}=1;
  8. }
  9. }
  10. },
  11. for_2d_map =&gt; sub {
  12. my %hash;
  13. my $limit = 100;
  14. for(my $i=0; $i&lt;$limit; $i++){
  15. $hash{$i} = {map { $_ =&gt; 1 } 0..$limit-1};
  16. }
  17. },
  18. for_2d_init_hash =&gt; sub {
  19. my %hash;
  20. my $limit = 100;
  21. for(my $i=0; $i&lt;$limit; $i++){
  22. my %tmp_hash;
  23. for(my $j=0; $j&lt;$limit; $j++){
  24. $tmp_hash{$j} = 1;
  25. }
  26. $hash{$i} = \%tmp_hash;
  27. }
  28. },
  29. for_2d_init_hash_w_array =&gt; sub {
  30. my %hash;
  31. my $limit = 100;
  32. my @array = (0..$limit-1);
  33. my @init = (1)x$limit;
  34. for(my $i=0; $i&lt;$limit; $i++){
  35. my %tmp_hash;
  36. @tmp_hash{@array} = @init;
  37. $hash{$i} = \%tmp_hash;
  38. }
  39. },
  40. for_2d_init_array =&gt; sub {
  41. my $limit = 100;
  42. my @init;
  43. $init[$_] = [(1)x$limit] for 0..$limit-1;
  44. },
  45. });

Results:

  1. for_2d_original: 2 wallclock secs ( 2.12 usr + 0.00 sys = 2.12 CPU) @ 744.81/s (n=1579)
  2. for_2d_map: 2 wallclock secs ( 2.19 usr + 0.00 sys = 2.19 CPU) @ 556.62/s (n=1219)
  3. for_2d_init_hash: 2 wallclock secs ( 2.21 usr + 0.00 sys = 2.21 CPU) @ 978.28/s (n=2162)
  4. for_2d_init_hash_w_array: 2 wallclock secs ( 2.15 usr + 0.00 sys = 2.15 CPU) @ 1558.14/s (n=3350)
  5. for_2d_init_array: 2 wallclock secs ( 2.10 usr + 0.00 sys = 2.10 CPU) @ 6018.57/s (n=12639)

huangapple
  • 本文由 发表于 2023年6月9日 11:29:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76437033.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定