执行数千次比较的最快方法
Posted
技术标签:
【中文标题】执行数千次比较的最快方法【英文标题】:Fastest way to perform thousands of comparisons 【发布时间】:2014-06-23 16:08:09 【问题描述】:我正在研究将 RGB 颜色转换为人类可读关键字的图像处理工具。 我需要:
-
初始化/声明 1000 个静态已知元素集
在动态元素和全部 1000 个元素之间执行 10 次比较(总共 10x1000 次比较)
重复第 1 步和第 2 步,上千张图像。
每个元素都是这样的结构:
struct KnownColor
cv::Scalar rgb;
std::string name;
std::vector<std::string> strings;
KnownColor ( cv::Scalar rgb, std::string name, std::vector<std::string> strings) :
rgb(rgb),
name(name),
strings(strings) ;
;
目前我正在使用静态std::vector<>
来存储它们。为了初始化这个向量,我目前正在使用一个名为 once 的函数,并将我的 1000 个元素推入向量中。每个结构都使用 KnownColor 构造函数进行初始化:
static std::vector<CustomStruct> Vector;
void vectorInit() //I call this only once per image:
...
Vector.push_back(KnownColor(Scalar(188,198,204),"Metallic Silver",std::vector<std::string>"gray"));
Vector.push_back(KnownColor(Scalar(152,175,199),"Blue Gray",std::vector<std::string>"gray","blue"));
... (1000 push_back in total)
比较函数,是返回最接近的“knownColor”及其人类可读关键字的标量之间的自定义欧几里德距离:
double min = std::numeric_limits<double>::max();
int index=0;
for(int i=0; i<KnownColors.size(); i++)
double tmp = scalarLABDistance(rgb,KnownColors[i].rgb);
if(tmp < distanceThreshold )
min = tmp;
break;
if(tmp < min )
min = tmp;
index = i;
return KnownColors[index].strings;
目前很遗憾,该程序是从 php 调用的,并且需要为每个图像(客户端请求)执行一次。
我想知道静态初始化是否会更好(初始化更快?迭代更快?),或者是否有更好的方法来比较静态元素集合而不使用std::vector
。
【问题讨论】:
您的性能关注的是初始化时间还是比较时间?您已经展示了初始化。大概初始化只发生一次。 您可以通过在第一次 push_back 之前调用 Vector.reserve(1000) 来加快初始化代码的速度。 什么样的比较?您是在比较绝对相等(这样您可以在第一次false
比较后短路)还是在做一些绝对需要每次都进行 1000 次比较的事情?
我们不知道你到底在做什么,所以没有办法知道最快的方法是什么。
@GuillermoMP:速度建议:看看您是否可以将其作为守护进程运行并通过本地 Unix 套接字进行通信。
【参考方案1】:
我在类似情况下所做的是编写一个程序来为我构建一个 C 文件,其中包含我需要已经整理好的数据结构。通常我用 Perl 或 Python 写这个。数据可能是生成的,也可能是从数据文件中读取的。
您可以在编译时构建一个 Boost 数组,这不需要时间进行初始化。但是,在任何桌面类型的 CPU 上,将 1000 个元素写入向量应该是超快的。
搜索你的 1000 个元素是一个更大的问题。
你说你在寻找欧几里得距离。游戏开发者用来解决这个问题的是一种称为二进制空间分区的技术。这可能会帮助你。它的工作方式非常粗略,是将 2D 空间划分为 4 个正方形。一个 3D 空间被分成 8 个立方体。然后将这些空间中的每一个进一步划分,直至最小的有用单元。这提供了一种快速搜索树的方法。但是,在搜索不适合一个分区的区域时会变得复杂。您可能决定搜索多棵树或在它接触的所有树中放置对象的副本。对于圆形或球体,您可能会退回到完美的距离计算,或者您可能只是将其细分为正方形/立方体,直到最小的单位并将其称为足够接近。有很多例子和文献。
而且,我几乎可以肯定你可以散列它,因为 2D BSP 中的一个点是一串 2 位位置值,它只是一个不同大小的整数,具体取决于你的 BSP 分辨率。
看起来另一个不错的选择可能是 kd-tree。那是一个“k”维树。我没有用过,但从我刚刚读到的关于它们的信息来看,它们看起来对这个很有用。
【讨论】:
-1 表示过早发布。等到问题被正确指定。 @KarolyHorvath:就在问题标题和他的第一段中。 不,不是。你有一堆不合理的假设,例如散列为评估比较提供了有意义的结果。 @KarolyHorvath:看起来他添加了一条评论说欧几里得距离,所以你是对的。我假设平等。我将更新答案以删除有关哈希表的内容,其余的可能仍然有用。 还有赞,我不是在搜索而是比较元素。我用详细信息扩展了这个问题。还是谢谢你。以上是关于执行数千次比较的最快方法的主要内容,如果未能解决你的问题,请参考以下文章
Python:仅使用 1 个外生变量执行数百万次简单线性回归的最快方法