- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
用 C++ 编码。我需要一堆排序字符串的数据结构。我将一次性将所有字符串插入其中而不更新它,但我会经常搜索字符串。我只需要查看结构中是否存在给定字符串。我希望该列表大约有 100 个字符串。
什么是更快的结构?一开始我在考虑 hashmap 但我在某处看到对于如此少量的元素,对 vector 进行二分搜索会更好(因为它们已排序)。
最佳答案
假设您正在谈论“全尺寸”CPU1,至少相对于其他解决方案,即使只有 100 个元素,对字符串进行二进制搜索也可能会很慢。您可能会因每次搜索而遭受多次分支预测错误,并且最终可能会多次检查输入字符串中的每个字符(因为您需要在二分搜索中的每个节点重复 strcmp
)。
正如有人已经指出的那样,唯一真正知道的方法是衡量 - 但要做到这一点,您仍然需要首先弄清楚候选人是什么!此外,并不总是可以在现实场景中进行测量,因为甚至可能不知道这样的场景(例如,想象一下,设计一个在许多不同情况下广泛使用的库函数)。
最后,了解什么可能是最快的可以让你排除你知道会表现不佳的候选人,并让你用你的直觉仔细检查你的测试结果:如果某些东西比你预期的慢得多,值得检查原因(编译器做一些愚蠢的事情),如果某些事情要快得多,那么也许是时候更新您的直觉了。
所以我会尝试真正尝试一下什么是快速的——假设速度在这里真的很重要,你可以花一些时间来验证一个复杂的解决方案。作为基准,一个简单的实现可能需要 100 ns,而真正优化的可能需要 10 ns。因此,如果您为此花费 10 个小时的工程时间,则必须调用此函数 4000亿次只是为了赚回你的 10 小时 5。当您将错误风险、维护复杂性和其他开销考虑在内时,您将需要确保在尝试优化此函数之前调用了数万亿次。这种功能很少见,但肯定存在4。
也就是说,您遗漏了许多帮助设计非常快速的解决方案所需的信息,例如:
std::string
或 const char *
或者是其他东西? gperf
它会吐出一个哈希函数和查找表。
gperf
它生成了一个哈希函数,只需要查看两个字符即可唯一区分每个单词,如下所示:
static unsigned int hash (const char *str, unsigned int len)
{
static unsigned char asso_values[] =
{
115, 115, 115, 115, 115, 81, 48, 1, 77, 72,
115, 38, 81, 115, 115, 0, 73, 40, 44, 115,
32, 115, 41, 14, 3, 115, 115, 30, 115, 115,
115, 115, 115, 115, 115, 115, 115, 16, 18, 4,
31, 55, 13, 74, 51, 44, 32, 20, 4, 28,
45, 4, 19, 64, 34, 0, 21, 9, 40, 70,
16, 0, 115, 115, 115, 115, 115, 115, 115, 115,
/* most of the table omitted */
};
register int hval = len;
switch (hval)
{
default:
hval += asso_values[(unsigned char)str[3]+1];
/*FALLTHROUGH*/
case 3:
case 2:
case 1:
hval += asso_values[(unsigned char)str[0]];
break;
}
return hval;
}
gperf
生成),并将得到的内容与输入字符串进行比较。
clang
生成这样的代码:
in_word_set: # @in_word_set
push rbx
lea eax, [rsi - 3]
xor ebx, ebx
cmp eax, 19
ja .LBB0_7
lea ecx, [rsi - 1]
mov eax, 3
cmp ecx, 3
jb .LBB0_3
movzx eax, byte ptr [rdi + 3]
movzx eax, byte ptr [rax + hash.asso_values+1]
add eax, esi
.LBB0_3:
movzx ecx, byte ptr [rdi]
movzx edx, byte ptr [rcx + hash.asso_values]
cdqe
add rax, rdx
cmp eax, 114
ja .LBB0_6
mov rbx, qword ptr [8*rax + in_word_set.wordlist]
cmp cl, byte ptr [rbx]
jne .LBB0_6
add rdi, 1
lea rsi, [rbx + 1]
call strcmp
test eax, eax
je .LBB0_7
.LBB0_6:
xor ebx, ebx
.LBB0_7:
mov rax, rbx
pop rbx
ret
char
中查找
str
值-> 在哈希函数表中查找
char
的哈希值-> 在实际哈希表中查找字符串),你预计这通常需要 20 个周期(当然还有
strcmp
时间)。
strcmp
strcmp
在某些时候 - 异常(exception)是布隆过滤器,它允许误报。所以你要确保这部分代码是快速的。
strcmp
的“内置”版本而不是调用库函数:在快速测试中
icc
做了内联,但是
clang
和
gcc
选择调用库函数。对于哪个更快,没有简单的规则,但通常库例程通常经过 SIMD 优化,对于长字符串可能更快,而内联版本避免了函数调用开销,对于短字符串可能更快。您可以测试这两种方法,并且主要是强制编译器在您的情况下执行更快的操作。
awk 'NR%990==0' /usr/share/dict/american-english > words
.
strcmp
在计算史上被称为?如果它快 1 ns 会节省多少时间?
关于用于多次搜索的 C++ 最快的数据结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40642021/
我在我的应用程序中使用 Hibernate Search。其中一个子集合被映射为 IndexedEmbedded。子对象有两个字段,一个是 id,另一个是日期(使用日期分辨率到毫秒)。当我搜索 id=
The App Engine Search API有一个 GeoPoint 字段。可以用它来进行半径搜索吗?例如,给定一个 GeoPoint,查找位于特定半径内的所有文档。 截至目前,它看起来像 Ge
客户对我正在做的员工管理项目提出了这个新要求,以允许他们的用户进行自定义 bool 搜索。 基本上允许他们使用:AND、OR、NOT、括号和引号。 实现它的最佳方法是什么?我检查了 mysql,它们使
很想知道哪个更快 - 如果我有一个包含 25000 个键值对的数组和一个包含相同信息的 MySQL 数据库,搜索哪个会更快? 非常感谢大家! 最佳答案 回答这个问题的最好方法是执行基准测试。 关于ph
我喜欢 smartcase,也喜欢 * 和 # 搜索命令。但我更希望 * 和 # 搜索命令区分大小写,而/和 ?搜索命令遵循 smartcase 启发式。 是否有隐藏在某个地方我还没有找到的设置?我宁
我有以下 Marklogic 查询,当在查询控制台中运行时,它允许我检索具有管理员权限的系统用户: xquery version "1.0-ml"; import schema namespace b
我希望当您搜索例如“A”时,所有以“A”开头的全名都会出现。因此,如果名为“Andreas blabla”的用户将显示 我现在有这个: $query = "SELECT full_name, id,
我想在我的网站上添加对人名的搜索。好友列表已经显示在页面上。 我喜欢 Facebook 这样做的方式,您开始输入姓名,Facebook 只会显示与查询匹配的好友。 http://cl.ly/2t2V0
您好,我在我的网站上进行搜索时遇到此错误。 Fatal error: Uncaught Error: Call to undefined function mysql_connect() in /ho
声明( 叠甲 ):鄙人水平有限,本文为作者的学习总结,仅供参考。 1. 搜索介绍 搜索算法包括深度优先搜索(DFS)和广度优先搜索(BFS)这两种,从起点开始,逐渐扩大
我正在为用户列表使用 FuturBuilder。我通过 futur: fetchpost() 通过 API 获取用户。在专栏的开头,我实现了一个搜索栏。那么我该如何实现我的搜索栏正在搜索呢? Cont
我正在使用 MVC5,我想搜索结果并停留在同一页面,这是我在 Controller (LiaisonsProjetsPPController) 中执行搜索操作的方法: public ActionRes
Azure 搜索中的两种方法 Upload 与 MergeOrUpload 之间有什么区别。 他们都做完全相同的事情。即,如果文档不存在,它们都会上传文档;如果文档已经存在,则替换该文档。 由于这两种
实际上,声音匹配/搜索的当前状态是什么?我目前正在远程参与规划一个 Web 应用程序,该应用程序将包含和公开记录的短音频剪辑(最多 3-5 秒,人名)的数据库。已经提出了一个问题,是否可以实现基于用户
在商业应用程序中,具有数百个面并不罕见。当然,并非所有产品都带有所有这些标记。 但是在搜索时,我需要添加一个方面查询字符串参数,其中列出了我想要返回的所有方面。由于我事先不知道相关列表,因此我必须在查
当我使用nvcc 5.0编译.cu文件时,编译器会为我提供以下信息。 /usr/bin/ld: skipping incompatible /usr/local/cuda-5.0/lib/libcud
我正在使用基于丰富的 Lucene 查询解析器语法的 Azure 搜索。我将“~1”定义为距离符号的附加参数)。但我面临的问题是,即使存在完全匹配,实体也没有排序。 (例如,“blue~1”将返回“b
我目前有 3 个类,一个包含 GUI 的主类,我在其中调用此方法,一个包含数据的客户类,以及一个从客户类收集数据并将其放入数组列表的 customerList 类,以及还包含搜索数组列表方法。 我正在
假设我有多个 6 字符的字母数字字符串。 abc123、abc231、abc456、cba123、bac231 和 bac123 。 基本上我想要一个可以搜索和列出所有 abc 实例的选择语句。 我只
我有这个表 "Table"内容: +--------+ | Serial | +--------+ | d100m | <- expected result | D100M | <- expect
我是一名优秀的程序员,十分优秀!