- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
std::binary_search
击败了一个简单的自制二进制搜索算法(再次):
// gcc version 4.8.2 X86_64
#ifndef EXAMPLE_COMPARE_VERSION
# define EXAMPLE_COMPARE_VERSION 0
#endif
static const long long LOOPS = 0x1fffffff;
#include <cassert>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#if EXAMPLE_COMPARE_VERSION
#include <algorithm>
inline bool stl_compare(const int l, const int r) {
return l < r;
}
#else
inline bool compare(const int *beg, const int *end, int v) {
for (const int *p; beg <= end;) {
p = beg + (end - beg) / 2;
if (*p < v) beg = p + 1;
else if (*p > v) end = p - 1;
else return true;
}
return false;
}
#endif
int main() {
const int arr[] = {
1784, 1785, 1787, 1789, 1794, 1796, 1797, 1801,
1802, 1805, 1808, 1809, 1912, 1916, 1918, 1919,
1920, 1924, 1925, 1926, 1929, 1930, 2040, 2044,
2047, 2055, 2057, 2058, 2060, 2061, 2064, 2168,
2172, 2189, 2193, 2300, 2307, 2309, 2310, 2314,
2315, 2316, 2424, 2429, 2432, 2433, 2438, 2441,
2448, 2552, 2555, 2563, 2565, 2572, 2573, 2680,
2684, 2688, 2694, 2697, 2699, 2700, 2704, 2705,
2808, 2811, 2813, 2814, 2816, 2818, 2822, 2826,
2827, 2828, 2936, 2957, 3064, 3070, 3072, 3073,
3074, 3075, 3076, 3077, 3078, 3081, 3082, 3084,
3085, 3086, 3088, 3192, 3196, 3198, 3200, 3205,
3206, 3211, 3212, 3213, 3326, 3327, 3328, 3330,
3331, 3333, 3337, 3338, 3339, 3344, 3448, 3449,
3451, 3452, 3454, 3459, 3461, 3462, 3465, 3469,
3472, 3578, 3585, 3588, 3593, 3594, 3704, 3712,
3715, 3722, 3723, 3852, 3972, 3973, 3974, 3980,
3982, 4088, 4090, 4091, 4092, 4094, 4096, 4098,
4099, 4100, 4101, 4102, 4103, 4105, 4106, 4107,
4108, 4109, 4110, 4216, 4220, 4222, 4223, 4224,
4226, 4227, 4229, 4230, 4233, 4234, 4235, 4238,
4240, 4350, 4354, 4361, 4369, 4476, 4480, 4486,
4600, 4614, 4735, 4864, 4870, 4984, 4991, 5004,
};
clock_t t = clock();
const size_t len = sizeof(arr) / sizeof(arr[0]);
for (long long i = 0; i < LOOPS; i++) {
int v = arr[rand() % len];
#if EXAMPLE_COMPARE_VERSION >= 2
assert(std::binary_search(arr, arr + len, v, stl_compare));
#elif EXAMPLE_COMPARE_VERSION
assert(std::binary_search(arr, arr + len, v));
#else
assert(compare(arr, arr + len, v));
#endif
}
printf("compare version: %d\ttime: %zu\n",
EXAMPLE_COMPARE_VERSION, (clock() - t) / 10000);
}
t.cc
)g++ t.cc -O3 -DEXAMPLE_COMPARE_VERSION=0 -o t0
g++ t.cc -O3 -DEXAMPLE_COMPARE_VERSION=1 -o t1
g++ t.cc -O3 -DEXAMPLE_COMPARE_VERSION=2 -o t2
./t2 ; ./t0 ; ./t1
在我的机器上输出(时间越短越快):
compare version: 2 time: 3533
compare version: 0 time: 4074
compare version: 1 time: 3968
当将 EXAMPLE_COMPARE_VERSION
设置为 0
时,我们使用自制的二进制搜索算法。
inline bool compare(const int *beg, const int *end, int v) {
for (const int *p; beg <= end;) {
p = beg + (end - beg) / 2;
if (*p < v) beg = p + 1;
else if (*p > v) end = p - 1;
else return true;
}
return false;
}
当将 EXAMPLE_COMPARE_VERSION
设置为 1
时,我们使用:
template <class ForwardIterator, class T>
bool binary_search (ForwardIterator first, ForwardIterator last,
const T& val);
当将 EXAMPLE_COMPARE_VERSION
设置为 2
时,我们使用:
template <class ForwardIterator, class T, class Compare>
bool binary_search (ForwardIterator first, ForwardIterator last,
const T& val, Compare comp);
// the Compare function:
inline bool stl_compare(const int l, const int r) {
return l < r;
}
这两个std::binary_search
函数定义在gcc 头文件目录的bits/STL_algo.h
中。
std::binary_search
使用比较函数 (t2) 比没有它的版本 (t1) 快得多?更新:
将 random()
替换为 rand()
,另请参阅 What difference between rand() and random() functions?
最佳答案
因为基准测试有缺陷。
random
:不仅它的运行时间有问题(并影响基准),而且还意味着您可能不会测量相同的运行时间基准现在,即使清除了瓦砾,您也可能会遇到标准算法比您自己的自制解决方案更快的情况。在这一点上,想想 C++ 的哲学:您不必为不需要的东西付费。因此,即使不进行优化,标准实现也可能至少 足够精简 与原始方法一样快:如果不是这样的话,它们已经修补了很长时间很久以前!
因此,最后,您需要检查差异。此时您需要深入研究代码并了解它是如何映射的。我建议使用源代码、LLVM IR 或程序集进行此探索(如果您不理解某些转换,请随时提问)。
也许正在进行一些展开?也许测试有更好的暗示?谁知道,在存在了几十年之后,您可能会发现一颗珍珠。
注意:要在 http://coliru.stacked-crooked.com 上获取 LLVM IR , 使用以下命令行 clang -O3 -S -emit-llvm -o main.ll main.cpp && cat main.ll
关于c++ - 为什么自制的二进制搜索算法比 std::binary_search 慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22934657/
我在我的应用程序中使用 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
我是一名优秀的程序员,十分优秀!