如何更高效地遍历存储{int,short,ushort,...}的字符数组?
我有一个 char data[len],它由从二进制文件读取的解压缩数据填充。 我知道 data
只能是以下类型:char、uchar、short、ushort、int、uint、float、double
我知道所需的确切位数表示 (elesize = {8, 16, 32, 64}
)。
我只想遍历数据列表,然后找到 max()
、min()
或给定数字的出现次数。我想在不创建另一个数组来解决内存空间问题的情况下执行此操作。
我想出了以下方法,但它很慢,例如 len == 34560000
所以我想知道是否有人有“one-liner”或更有效的方法来做到这一点(C 或C++)。
char data[len];
double mymax = -std::numeric_limits<double>::max()
for (size_t i=0; i<len; i += elesize)
{
double x;
char *r = data+i;
if (elementtype == "char")
x = static_cast<double>(*r);
else if (elementtype == "uchar")
x = static_cast<double>(*((unsigned char *)r));
else if (elementtype == "short")
x = static_cast<double>(*((int16_t *)r));
else if (elementtype == "ushort")
x = static_cast<double>(*((uint16_t *)r));
else if (elementtype == "int")
x = static_cast<double>(*((int32_t *)r));
else if (elementtype == "uint")
x = static_cast<double>(*((uint32_t *)r));
else if (elementtype == "float")
x = static_cast<double>(*((float *)r));
else if (elementtype == "double")
x = *((double *)r);
if (x > mymax)
mymax = x;
}
I have a char data[len]
populated from unzipped data that is read off of a binary file.
I know that data
can only be of these types: char, uchar, short, ushort, int, uint, float, double
for which I know exact number of bits needed to represent (elesize = {8, 16, 32, 64}
).
I just want to traverse the data list and, say, find the max()
, min()
or number of occurrences of a given number. and I want to do this without creating another array for memory space concerns.
I have come up with the following but it is slow for example for len == 34560000
So I was wondering if anyone has a 'one-liner' or a more efficient way for doing this (either C or C++).
char data[len];
double mymax = -std::numeric_limits<double>::max()
for (size_t i=0; i<len; i += elesize)
{
double x;
char *r = data+i;
if (elementtype == "char")
x = static_cast<double>(*r);
else if (elementtype == "uchar")
x = static_cast<double>(*((unsigned char *)r));
else if (elementtype == "short")
x = static_cast<double>(*((int16_t *)r));
else if (elementtype == "ushort")
x = static_cast<double>(*((uint16_t *)r));
else if (elementtype == "int")
x = static_cast<double>(*((int32_t *)r));
else if (elementtype == "uint")
x = static_cast<double>(*((uint32_t *)r));
else if (elementtype == "float")
x = static_cast<double>(*((float *)r));
else if (elementtype == "double")
x = *((double *)r);
if (x > mymax)
mymax = x;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
模板应该做得很好:
用法:
废弃这个,我以为最初问题是针对 C 的。
这是一个宏:
用法:
你并没有真正绕过指定 < em>类型,不过。在 C++ 中,这可以做得更优雅一些。
或者,您可以将其全部包装在一个中:
A template should do nicely:
Usage:
Scrap this, I thought originally the question was for C.
Here's a macro:
Usage:
You don't really get around specifying the type, though. In C++ this could be done a bit more elegantly.
Alternatively you can wrap it all in one:
鉴于
elementtype
是循环不变的,您最好只在for
之外进行一次比较。顺便说一句,我希望elementtype
是std::string
类型或与字符串文字进行有意义比较的类型。最终,我将编写一个模板函数来执行整个处理循环,然后根据
elementtype
使用适当的模板参数调用它。Given that
elementtype
is loop-invariant, you would better do the comparison only once outside thefor
. By the way, I hopeelementtype
is of typestd::string
or something that meaningfully compares to string literals.Ultimately, I would write a template function that does the whole processing loop and then call it with the appropiate template argument according to
elementtype
.将条件代码放在循环之外,因此循环运行得很快。尝试这样的事情:
Put the conditional code outside the loop, so the loop runs fast. Try something like this:
正如其他人指出的,您应该只检查类型一次。然后您应该调用仅处理一种类型的适当子函数。当元素类型不是双精度时,您也不应该转换为双精度来与 my_max 进行比较。否则,您将不必要地转换为双精度并与双精度进行比较。如果 elementtype 是 uint,那么您永远不应该将任何内容转换为 double,只需与也是 uint 的 my_max var 进行比较。
As others indicated, you should check the type only once. Then you should call appropriate sub-function that only deals with one type. You should also not be casting to doubles for comparing to my_max when the elementtype is not double. Otherwise you are needlessly converting to double and doing comparisons with doubles. If elementtype is uint, then you should never be converting anything to double, just compare with a my_max var that is also uint.