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 中大型哈希表的快速加载 的相关文章

  • 与 Java 7 相比,Java 8 ScriptEngine 的主要性能问题

    我有一个 Java 程序 使用 JDK 7u80 编译 它广泛使用了 JavaScript ScriptEngine JSR 223 我注意到 与 Java 7 运行时环境 JRE 7u80 相比 我的程序在 Java 8 运行时环境 JR
  • 如何在 Perl 脚本中递归查找文件/文件夹?

    我有一个 perl 脚本 我编写了该脚本来递归地搜索 Windows 文件夹中的文件 我输入搜索文本作为 perl 脚本运行时参数 以查找名称中包含此文本的文件 perl脚本如下 use Cwd file1 ARGV 0 res1 glob
  • DBI:在 eval 中引发错误

    这个问题参考了池上的评论 But if you re going to put an eval around every statement just use RaiseError gt 0 in this thread https sta
  • PostgreSQL:存在与左连接

    我多次听说 postgres 处理exists查询速度更快左连接 http archives postgresql org pgsql performance 2002 12 msg00185 php http archives postg
  • 如何加速Python循环

    我查看了几个网站上的一些讨论 但没有一个给我解决方案 这段代码运行时间超过5秒 for i in xrange 100000000 pass 我正在研究整数优化问题 我必须使用O n log n 算法编辑 O n 4 算法 其中n代表矩阵的
  • 读取 CSV 文件单列的更快方法

    我正在尝试阅读一个列CSV文件至R尽快 我希望将标准方法将列放入 RAM 所需的时间减少 10 倍 我的动机是什么 我有两个文件 一个叫Main csv这是 300000 行和 500 列 其中一个称为Second csv即 300000
  • Java Keystore 是否存在性能问题? [复制]

    这个问题在这里已经有答案了 我们开发了一个应用程序来加密 解密来自服务器的请求 响应 我们正在做性能测试 加密 解密应用程序 我们观察到加密 解密过程需要时间 而许多线程 正在同时做 为了识别问题 我们记录了加密 解密过程中的所有方法 从记
  • “const”声明是否有助于编译器(GCC)生成更快的代码? [复制]

    这个问题在这里已经有答案了 Do const声明有助于编译器 GCC 生成更快的代码 还是仅对可读性和正确性有用 泽德 肖认为const在 C C 中无用或过度使用 接下来是对 const 的所有奇怪的迷恋 由于某些奇怪的原因 C 喜欢让你
  • 返回空字符串:C++ 中的有效方法

    我有两种从函数返回空字符串的方法 1 std string get string return 2 std string get string return std string 哪一种更有效 为什么 Gcc 7 1 O3 这些都是相同的
  • 什么时候汇编比C更快? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的
  • Java中使用final关键字会提高性能吗?

    在 Java 中 我们看到很多地方final可以使用关键字 但其使用并不常见 例如 String str abc System out println str 在上述情况下 str can be final但这通常被忽略 当一个方法永远不会
  • 在 Perl 中,如何从父进程向子进程发送消息(或信号),反之亦然?

    我正在编写一个管理多进程的程序 这就是我所做的 而且效果很好 但现在 我想将消息从子进程发送到父进程 反之亦然 从父进程到子进程 你知道最好的方法吗 你知道我所做的是否是我想要的正确方法 从子进程到父进程发送消息 信号或共享内存 反之亦然
  • 矩阵求逆 (3,3) python - 硬编码与 numpy.linalg.inv

    对于大量矩阵 我需要计算定义为的距离度量 尽管我确实知道强烈建议不要使用矩阵求逆 但我没有找到解决方法 因此 我尝试通过对矩阵求逆进行硬编码来提高性能 因为所有矩阵的大小均为 3 3 我预计这至少会是一个微小的改进 但事实并非如此 为什么
  • 网站性能衡量

    我需要一个免费的工具来测量网站的性能 并且不需要对代码 jsp asp 页面 进行任何更改 感谢所有帮助 对于绩效衡量 我建议您YSlow http developer yahoo com yslow 它是一个 Firefox 插件 集成了
  • 如何提高 MongoDB 中 update() 和 save() 的性能?

    我正在寻找有关如何在以下情况下提高数据库性能的提示 作为示例应用程序 我今天编写了一个相当简单的应用程序 它使用 Twitter 流 API 来搜索某些关键字 然后将结果存储在 MongoDB 中 该应用程序是用 Node js 编写的 我
  • Oh-my-zsh 哈希(井号)符号错误模式或未找到匹配项

    我很确定是与我的 Oh my zsh 配置相关的东西 但我不知道它是什么 当我在 git 命令中使用 符号时 但也适用于其他所有命令 例如 ls 2 我收到 错误模式 错误或 找不到匹配项 我猜是要计算一些东西 但我找不到在哪里配置它 I
  • 如何在 Linux 上使用 Mono 将 Perl 解释器嵌入到我的 C# 程序中?

    有谁知道是否可以在 C 中从 Mono 调用 Perl 子程序 这是在 Linux 机器上 Maybe DllImport 如果可能的话 我们也希望避免每次都加载 perl Interop 可以在 Linux 下与 Mono 很好地调用 C
  • time() 会返回相同的输出吗?

    当用户注册时 我正在为 PHP 中的用户生成令牌 我想知道两个用户是否可以获得相同的令牌 因为这会破坏系统 请让我知道这是否足够 token md5 rand time 编辑 我现在正在使用我在另一个问题上找到的generate uuid
  • LockBits 性能关键代码

    我有一个方法需要尽可能快 它使用不安全的内存指针 这是我第一次尝试这种类型的编码 所以我知道它可能会更快
  • hashlib 和 urandom 哪个更随机?

    我正在和一个朋友一起开发一个项目 我们需要生成随机哈希 在我们有时间讨论之前 我们都提出了不同的方法 并且因为他们使用不同的模块 我想问你们大家什么会更好 如果有这样的事情的话 hashlib sha1 str random random

随机推荐