【问题标题】:fast retrieval of (void *) memory block快速检索 (void *) 内存块
【发布时间】:2010-09-15 22:13:04
【问题描述】:

我有一个将 void* 返回到内存块的系统。此内存块存储不同类型(int、char、double 等)的连续数据记录,并给出每条记录中每个字段的字节数。我本质上是查找记录的类型并获取记录的值。要检索所有记录,我会这样做

switch(type)

{

   case 'int' : \*(int*)(ptr+index)

   case 'char': \*(char*)(ptr+index)

}

当我必须浏览 300000 条记录时,这会花费很多时间。有没有更快的方法来浏览所有记录?

【问题讨论】:

  • 您能否发布(并正确格式化)真实代码?这不可能是正确的。
  • 定义“很多时间”。我们说的是微秒还是秒?如果是后者,那么您很可能正在将内存交换到磁盘,并且只能通过更多 RAM 来解决。 300,000 条记录并没有那么大,简单地访问这 300,000 条记录的内存应该会非常快。
  • 秒。在每个切换案例中,我将值附加到 ostringstream。这需要更长的时间吗?
  • CC++?我相信这个答案对于不同的语言可能会有很大的不同......
  • @Rajesh:您的代码不是合法的 C 或 C++。然而,答案取决于。这取决于你对值做什么,你从哪里得到这个内存块等等。你怎么知道 switch 语句是一个瓶颈?你用过探查器吗?我简直不敢相信 switch 是个问题。

标签: c++ c


【解决方案1】:

如果单个块可以是只能在运行时解析的多种类型,则必须在 switch 语句中分派给处理程序。请注意:

  1. unions 通常在 C 中用于此类事情以节省空间
  2. switch 语句非常快,并且可以转换为常数时间查找表

【讨论】:

  • 它实际上是各种类型的连续内存..like int,char,int,double...所以它将是 4 字节、1 字节、4 字节、8 字节等
  • @Eli,switch 语句不保证是常数时间查找表。这取决于编译器是否可以优化它。
  • @Vlad:我假设对于作者要求的简单情况(在enum 或小整数上使用switch 发送)今天的编译器会优化它
  • @Rajesh:给定一个二进制数据流,你怎么知道接下来的 4 个字节是 int 还是 double 的开头?
  • 我得到了每条记录的起点及其数据类型/大小
【解决方案2】:

如果我正确理解您的问题 - 我假设您正在浏览每条记录,有点说“对于每条记录 i,如果其类型为 'char',则访问位置 i 的记录”。

如果你事先知道要访问多少条记录,你就不能先把它们全部缓存起来吗?

如果我完全偏离轨道,请原谅我不理解您的观点。

【讨论】:

  • 缓存?..它们已经在内存中了..我得到了指向第一个位置的指针
【解决方案3】:

您的 cmets 终于提供了足够的信息来回答这个问题:您正在写信给 ostringstream。这意味着您可能在交换机内部进行了大量的字符串操作。弄清楚如何优化它,你的性能问题应该会消失。

(为了说服自己是这种情况,只需注释掉所有引用流的代码并再次运行您的程序)

【讨论】:

  • 我做的唯一操作是读入一个ostringstream,我用它作为序列化的一种方式通过套接字发送。有更好的选择吗?
猜你喜欢
  • 2021-03-09
  • 2011-09-30
  • 2011-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多