Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 寻找最有效的数据结构来创建索引文件_C++_Performance_Data Structures_Big O_Video Capture - Fatal编程技术网

C++ 寻找最有效的数据结构来创建索引文件

C++ 寻找最有效的数据结构来创建索引文件,c++,performance,data-structures,big-o,video-capture,C++,Performance,Data Structures,Big O,Video Capture,我有一个视频文件,它由许多连续的二进制数据帧组成。每个帧还有一个唯一的时间戳(它不是文件中的序列号,而是摄像机在记录时提供的值)。另一方面,我有一个API函数,它根据帧的序列号检索该帧。让事情变得更复杂一点——我有一个播放器,它提供了时间戳,并且应该获得该帧的二进制数据 另一件可悲的事情是:时间戳不是连续的。它们可以是连续的,但不能保证,因为环绕可能发生在最大无符号短大小附近。 所以时间戳序列可以是 54567, 54568, ... , 65535, 65536 , ... 或 54567,5

我有一个视频文件,它由许多连续的二进制数据帧组成。每个帧还有一个唯一的时间戳(它不是文件中的序列号,而是摄像机在记录时提供的值)。另一方面,我有一个API函数,它根据帧的序列号检索该帧。让事情变得更复杂一点——我有一个播放器,它提供了时间戳,并且应该获得该帧的二进制数据

另一件可悲的事情是:时间戳不是连续的。它们可以是连续的,但不能保证,因为环绕可能发生在最大无符号短大小附近。 所以时间戳序列可以是 54567, 54568, ... , 65535, 65536 , ... 或
54567,54568,…,65535,0,1

因此,它可能如下所示:

Frame 0
timestamp 54567
binary data
........
Frame 1
timestamp 54569
binary data
........
Frame 2
timestamp 54579
binary data
.
.
.
Frame n
timestamp m
binary data

0 <= n <= 65536 (MAX_UNSIGNED_SHORT)
0 <= m <= MAX_UNSIGNED_INT
第0帧
时间戳54567
二进制数据
........
第1帧
时间戳54569
二进制数据
........
第2帧
时间戳54579
二进制数据
.
.
.
帧n
时间戳m
二进制数据

0这里有一系列的权衡

您的索引文件已经是一个数据结构的转储:一个数组。如果您不打算经常插入或删除帧,并将此数组保持在排序顺序中,则可以很容易地对数组执行二进制搜索(使用
std::binary_search
)。插入和删除采用O(N),但搜索仍然是O(logn)。数组将占用更少的内存空间,并且从索引文件读取和写入的速度更快


如果您正在进行大量的插入和删除帧,那么转换为
std::map
结构将提供更好的性能。如果帧的数量很大,或者您想用它们存储更多的元数据,那么您可能需要查看一个,或者只使用像或这样的嵌入式数据库。这两种方法都实现了B树索引,并且都是经过良好测试的代码。

我们似乎应该能够做出以下假设: a) 视频文件本身在创建后不会被修改 b) 播放器可能希望在正常播放时找到连续帧 c) 玩家可能希望找到随机帧,即在进行FF、REW或跳过或跳到章节时


考虑到这一点,为什么不只做一个将帧Id和帧索引关联起来的HashMap呢?您可以创建一次,播放器可以读取它,然后可以对请求的帧进行简单且有时间限制的查找。

只需将帧数据存储在一个数组中,其中索引表示帧编号。然后创建一个从相机索引到帧编号的散列映射。您可以在O(1)中获取属于帧编号或摄影机索引的帧,同时仅使用比当前方法更多的内存

或者,您可以维护一个按帧编号索引的数组,该数组存储(摄影机索引,数据)对,并在需要按摄影机索引访问时对其执行O(logn)二进制搜索。这利用了摄影机索引已排序的事实

<>在C++的标准库中,散列映射可用为> STD::unOrdEdEdMult/<代码>(如果编译器/ STL支持它们,这可能不是因为它们最近才被添加到C++标准),尽管基于树的代码> STD::MAP< /COD>(用O(log n)查找)可能足够好用于这个目的。
二进制搜索的实现方式是
std::binary_search

二者之间没有相关性(除了它们都在严格增加)?我猜“帧索引”是一个时间戳?不会严格影响你将得到的答案,但名称有点笨拙。您可能会在开放的“框架索引”中找到一些有用的信息,可以将其视为“时间戳”。我同意这些并不是最好的名称:(你是说
std::unordered_map
,而不是
HashMap
。这是个不错的主意,不过,如果帧数很小,那么hash函数可能比搜索二叉树或排序数组花费更多。这是一个公平点,但帧数通常相当大(我以前在摩托罗拉的视频点播组工作)。当然,这取决于你是在播放10-30秒的广告还是2小时的电影:-)我在图像分析方面的大部分工作都是在200帧或更少(更长,信号通常会变淡)的细胞电影上进行的。遗憾的是,几乎没有完美和通用的解决方案。@JerryCoffin建议的插值搜索似乎对这一特定数据是个好主意。目前的帧数不会超过65536