Perl 中大型哈希表的快速加载

2024-04-19

我有大约 30 个文本文件,其结构如下

wordleft1|wordright1
wordleft2|wordright2
wordleft3|wordright3
...

文件总大小约1GB,包含约3200万行单词组合。

我尝试了几种方法来尽可能快地加载它们并将组合存储在哈希中

$hash{$wordleft} = $wordright

逐个文件打开并逐行读取大约需要 42 秒。然后我使用可存储模块存储哈希值

store \%hash, $filename

再次加载数据

$hashref = retrieve $filename

将时间缩短至约 28 秒。我使用快速 SSD 驱动器和快速 CPU,并有足够的 RAM 来保存所有数据(大约需要 7 GB)。

我正在寻找一种更快的方法来将此数据加载到 RAM 中(由于某些原因我无法将其保留在那里)。


您可以尝试使用 Dan Bernstein 的 CDB 文件格式并使用绑定哈希,这将需要最少的代码更改。您可能需要安装CDB_File http://search.cpan.org/~toddr/CDB_File-0.98/CDB_File.pm。在我的笔记本电脑上,cdb 文件打开速度非常快,每秒可以执行大约 200-250k 次查找。以下是创建/使用/基准测试 cdb 的示例脚本:

测试_cdb.pl

#!/usr/bin/env perl

use warnings;
use strict;

use Benchmark qw(:all) ;
use CDB_File 'create';
use Time::HiRes qw( gettimeofday tv_interval );

scalar @ARGV or die "usage: $0 number_of_keys seconds_to_benchmark\n";
my ($size)    = $ARGV[0] || 1000;
my ($seconds) = $ARGV[1] || 10;

my $t0;
tic();

# Create CDB
my ($file, %data);

%data = map { $_ => 'something' } (1..$size);
print "Created $size element hash in memory\n";
toc();

$file = 'data.cdb';
create %data, $file, "$file.$$";
my $bytes = -s $file;
print "Created data.cdb [ $size keys and values, $bytes bytes]\n";
toc();

# Read from CDB
my $c = tie my %h, 'CDB_File', 'data.cdb' or die "tie failed: $!\n";
print "Opened data.cdb as a tied hash.\n";
toc();

timethese( -1 * $seconds, {
          'Pick Random Key'    => sub { int rand $size },
          'Fetch Random Value' => sub { $h{ int rand $size }; },
});

tic();
print "Fetching Every Value\n";
for (0..$size) {
    no warnings; # Useless use of hash element
    $h{ $_ };
}
toc();

sub tic {
    $t0 = [gettimeofday];    
}

sub toc {
    my $t1 = [gettimeofday];
    my $elapsed = tv_interval ( $t0, $t1);
    $t0 = $t1;
    print "==> took $elapsed seconds\n";
}

输出(100万个按键,测试超过10秒)

./test_cdb.pl 1000000 10

Created 1000000 element hash in memory
==> took 2.882813 seconds
Created data.cdb [ 1000000 keys and values, 38890944 bytes]
==> took 2.333624 seconds
Opened data.cdb as a tied hash.
==> took 0.00015 seconds
Benchmark: running Fetch Random Value, Pick Random Key for at least 10 CPU seconds...
Fetch Random Value: 10 wallclock secs (10.46 usr +  0.01 sys = 10.47 CPU) @ 236984.72/s (n=2481230)
Pick Random Key:  9 wallclock secs (10.11 usr +  0.02 sys = 10.13 CPU) @ 3117208.98/s (n=31577327)
Fetching Every Value
==> took 3.514183 seconds

输出(1000万个按键,测试超过10秒)

./test_cdb.pl 10000000 10

Created 10000000 element hash in memory
==> took 44.72331 seconds
Created data.cdb [ 10000000 keys and values, 398890945 bytes] 
==> took 25.729652 seconds
Opened data.cdb as a tied hash.
==> took 0.000222 seconds
Benchmark: running Fetch Random Value, Pick Random Key for at least 10 CPU seconds...
Fetch Random Value: 14 wallclock secs ( 9.65 usr +  0.35 sys = 10.00 CPU) @ 209811.20/s (n=2098112)
Pick Random Key: 12 wallclock secs (10.40 usr +  0.02 sys = 10.42 CPU) @ 2865335.22/s (n=29856793)
Fetching Every Value
==> took 38.274356 seconds
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Perl 中大型哈希表的快速加载 的相关文章

  • 真实文件对象比 StringIO 和 cStringIO 慢?

    StringIO其代码中有以下注释 Notes Using a real file is often faster but less convenient There s also a much faster implementation
  • 为什么我不应该使用 UNIVERSAL::isa?

    根据这个 http perldoc perl org UNIVERSAL html http perldoc perl org UNIVERSAL html 我不应该使用 UNIVERSAL isa 而应该使用 obj gt isa 或 C
  • 如何添加到 Ruby 中的现有哈希

    关于添加一个key gt value与 Ruby 中现有的填充哈希配对 我正在学习 Apress 的 Beginning Ruby 并且刚刚完成了哈希章节 我试图找到最简单的方法来使用哈希实现与数组相同的结果 x 1 2 3 4 x lt
  • 性能 - String.charAt(0) 与 /^.{1}/

    从概念上讲哪个应该更快 String charAt 0 or 1 regex String charAt 0 必须处理和应用正则表达式 速度测试资源 Paul S https stackoverflow com users 1615483
  • 如何从 Hudson CI API 获得更好的性能?

    我正在尝试为自己编写一个与 Hudson 构建服务器集成的小工具 我目前遇到的障碍是性能 我想做一件简单的事情 比如列出所有作业和上次成功构建的时间 hudson API 提供了此信息 但我要么必须查询所有内容depth 2或者单独查询每个
  • 样式组件如何影响性能?

    使用样式组件是否比样式表更会降低 Web 应用程序的速度 如果我关心性能并且没有任何依赖于 props 的样式 我是否应该放弃样式组件并使用样式表 当您有很多小组件时 同时使用样式化组件渲染 性能开销可能会很有意义 绝对值得测试以删除小元素
  • 如何在没有 __hash__ 的情况下删除对象列表中的重复项

    我有一个自定义对象列表 我想从中删除重复项 通常 您可以通过定义两者来做到这一点 eq and hash 为你的对象 然后采取set的对象列表 我已经定义了 eq 但我想不出一个好的实现方法 hash 这样它对于相等的对象返回相同的值 更具
  • 如何比较两个文件中的多列并在找​​到匹配时从另一列检索相应的值

    我有两个文件 File1 txt 和 File2 txt 我需要将 File1 中的三列 1 2 和 3 分别与 File2 的 4 5 和 6 进行比较 如果找到匹配项 我想从 File2 的第 2 列中检索相应的值并将其粘贴到输出中 T
  • 非阻塞方法中的饥饿

    一段时间以来 我一直在阅读有关非阻塞方法的内容 这是一段所谓的无锁计数器的代码 public class CasCounter private SimulatedCAS value public int getValue return va
  • 如何在 Perl 中使用 use strict 一次一行处理多行字符串?

    我正在尝试找出 PBP 批准的正确方法来一次一行处理多行字符串 许多 Perl 编码人员建议将多行字符串视为文件句柄 除非您在脚本中使用 use strict 否则它可以正常工作 然后 您会收到编译器发出的警告 提示在使用严格引用时无法使用
  • 从视频创建缩略图 - 提高速度性能 - AVAsset - iPhone [重复]

    这个问题在这里已经有答案了 我正在使用基于以下线程中的代码的代码来生成视频缩略图 从 iPhone SDK 中的视频 URL 或数据获取缩略图 https stackoverflow com questions 1347562 gettin
  • 迭代哈希数组

    我编写了下面的例程 迭代哈希值 0 7 并打印出每个哈希值中特定键的值 我需要获取每个哈希中 b4 的值 我想取消 0 7 当存在不同数量的哈希值时使用更智能的东西 例如 有时只有 2 个 也可能有 160 个 my out decode
  • 双线性序列给出奇数结果

    我试图让我的表现技能 不存在 达到标准 但在将公式写入代码时遇到了问题 这是我试图将其引用为 转换 为代码的公式 考虑一个序列 u 其中 u 定义如下 号码u 0 1是第一个u 对于每个x in u then y 2 x 1 and z 3
  • Perl Tk 模块有哪些缺点?

    与在 Perl 中创建 GUI 的其他解决方案相比 Tk 模块有哪些缺点 我最近浏览了 Perl 的各种 gui 模块 这是我的总结 免责声明 最终我发现现有模块都不能满足我的需求 所以我开始编写自己的 gui 工具包 Tk 工作起来很不错
  • 如何有效地从 DB2 表中删除所有行

    我有一个大约有 50 万行的表 我想删除所有行 如果我做简单的delete from tbl 事务日志已满 我不关心这种情况下的事务 无论如何我都不想回滚 我可以删除许多事务中的行 但是有更好的方法吗 如何有效地从 DB2 中的表中删除所有
  • 对于双核手机,availableProcessors() 返回 1

    我最近购买了一部 Moto Atrix 2 手机 当我尝试查看手机中的处理器规格时 Runtime getRuntime availableProcessors 返回 1 proc cpuinfo 也仅包含有关处理器 0 的信息 出于好奇
  • Perl 和 Unix 如何以相同的顺序对 Unicode 字符串进行排序?

    我正在尝试获取 Perl 和 GNU Linuxsort 1 程序就如何对 Unicode 字符串进行排序达成一致 我在跑sort with LANG en US UTF 8 在Perl程序中我尝试了以下方法 use Unicode Col
  • 如何确保我的代码永远不会直接退出?

    eval require file subsequent code goes here If file包含一个exit语句 后面的代码就没有机会运行 如何解决以便后续代码始终有机会运行eval已经完成了 中止是不可能的exit call f
  • 在 nHibernate 关系中使用实体的 Lite 版本?

    在某些情况下 出于性能原因 创建一个实体的轻量级版本 指向同一个表 但映射的列较少 这是一个好主意吗 例如 如果我有一个包含 50 列的联系人表 并且在一些相关实体中 我可能对 FirstName 和 LastName 属性感兴趣 那么创建
  • 改变字典的哈希函数

    按照此question https stackoverflow com questions 37100390 towards understanding dictionaries 我们知道两个不同的字典 dict 1 and dict 2例

随机推荐