C 将结构与零进行比较的首选方法

C 将结构与零进行比较的首选方法,c,data-structures,comparison,C,Data Structures,Comparison,今天我遇到了一种情况,我需要确定由大约40个元素组成的整个结构是否为零,这意味着每个元素都为零。 在考虑如何使其尽可能快速高效时,我想到了三种不同的方法: 将每个元素比较为零,得到40条if语句 分配一个类似的结构,该结构已调零,并且memcmp与该结构一起使用 用足以覆盖整个结构的字体将结构包裹在一个接头中 比如说 typedef union { struct { uint8_t a; uint8_t b; } uint16_t c; } STRUCTURE_

今天我遇到了一种情况,我需要确定由大约40个元素组成的整个结构是否为零,这意味着每个元素都为零。
在考虑如何使其尽可能快速高效时,我想到了三种不同的方法:

  • 将每个元素比较为零,得到40条if语句
  • 分配一个类似的结构,该结构已调零,并且
    memcmp
    与该结构一起使用
  • 用足以覆盖整个结构的字体将结构包裹在一个接头中
  • 比如说

    typedef union {
      struct {
        uint8_t a;
        uint8_t b;
        }
      uint16_t c;
     } STRUCTURE_A;
    
    然后将其与零进行比较

    我想知道您对这些解决方案的看法,您认为哪种解决方案最快、最有效。
    如果你想找到更好的方法,请告诉我…

    谢谢。

    将结构的每个成员与0进行比较

    这是比较两个structures对象的唯一安全方法(即使其中一个structures对象的所有成员都设置为0)。不要使用
    memcmp
    来比较结构,结构中填充字节的值未指定。还请注意,不允许对结构对象操作数使用
    =
    运算符

    请参阅有关结构对象比较的c-faq链接:


    如果您的结构大小是以确保代码清晰,并且正如其他人所指出的,为了避免填充引起的问题,最好检查每个成员

    对于速度,从这样的东西开始,检查每个字节是否为零

    int iszero(void * ptr, int bytes )
    {
       char * bptr = (char*)ptr;
       while( bytes-- )
         if( *bptr++ )
             return 0;
      return 1;
    }
    

    然后优化以进行单词对齐的比较。查看newlib的strlen()&
    memcpy()
    等实现,了解如何实现这些功能的示例。

    if
    语句中简单地检查整个结构有什么错,比如检查零标志?您是否实现了三种不同的方法并比较了它们的性能?你发现了什么?由于可能的原因,除了比较每个字段之外,我看不到一种可移植的方法padding@Platinum-填充位、未初始化成员(可能并非所有有效数据配置都需要)、概念上为“false”时可能为非零的成员,随着应用程序的扩展,上述任何一项都会在将来的某个时候发生变化。它是否尽可能高效有关系?如果您已确保结构不包含填充,
    memcmp
    是安全的。虽然技术上允许一个实现添加任意无意义的填充,但在现实世界中,填充纯粹是为了对齐,并且一个正确构造的、自然对齐的结构将没有填充,除非可能在最后。特别是,使用
    intX\u t
    并在没有对齐间隙的情况下对它们进行排序是避免任何填充的好方法。如果结构不包含填充,并且
    memcmp
    实际上更快,优化器肯定会看到这一点并相应地转换比较。这相当于
    memcmp
    ,并且可能存在填充问题。@R。。不,它不等同于memcmp(),因为这里没有多余的零结构。memcmp()中的额外内存访问可能比内存访问时间的两倍还要糟糕,因为每次都要进行两次读取,并且可能会在大型结构上造成缓存损坏。我没有考虑过填充问题。但是如果你知道没有填充(例如,在GCC中使用pragma pack),我会坚持我的观点,即这种技术是最快的。所谓“等效”,我的意思是它具有相同的行为(和填充问题),但我请你比较性能。您的代码(逐字节)非常慢,即使进行多次读取,
    memcmp
    也会获胜。好的
    memcmp
    一次比较4、8甚至16个字节。顺便说一句,“打包”不是解决对齐问题的方法。我对ouah答案的评论是正确的。@R。我将其作为练习留给OP,并提供newlib作为参考impl。是的,您应该注意对结构中的字段进行排序,以减少填充的需要,这并不总是消除填充,而是将其移动到末尾。然后,当你有嵌套结构时,你的理论就会出现在窗口中,因为你突然又在中间填充了。R,我应该补充一下,我很清楚没有任何结构打包技术是完全可移植的,但是我在野外遇到的每个C编译器都有一些打包你的结构的技术。我还知道,将结构紧密打包可能会影响访问非对齐int等的性能。