我有一个类似于C数组的数据结构:
char byte_array[10];
还有一个作为掩模的:
char byte_mask[10];
我想通过按位运算符在每个字节上对第一个数组和第二个数组进行操作,得到另一个数组作为结果。
怎样才能以最高效的方式完成这个任务?
谢谢您的回答。
我有一个类似于C数组的数据结构:
char byte_array[10];
还有一个作为掩模的:
char byte_mask[10];
我想通过按位运算符在每个字节上对第一个数组和第二个数组进行操作,得到另一个数组作为结果。
怎样才能以最高效的方式完成这个任务?
谢谢您的回答。
for ( i = 10 ; i-- > 0 ; )
result_array[i] = byte_array[i] & byte_mask[i];
这适用于所有数组和处理器。但是,如果您知道您的数组是单词对齐的,则更快的方法是将其转换为较大的类型并进行相同的计算。
例如,假设 n=16
而不是 n=10
。那么这将更快:
uint32_t* input32 = (uint32_t*)byte_array;
uint32_t* mask32 = (uint32_t*)byte_mask;
uint32_t* result32 = (uint32_t*)result_array;
for ( i = 4 ; i-- > 0 ; )
result32[i] = input32[i] & mask32[i];
(当然,您需要一个适当的类型来表示 uint32_t
,如果 n
不是2的幂,则需要清除开头和/或结尾,以使32位内容对齐。)如果希望程序更快,确保byte_array的长度是4的倍数(64位系统上为8的倍数),然后:
char byte_array[12];
char byte_mask[12];
/* Checks for proper alignment */
assert(((unsigned int)(void *)byte_array) & 3 == 0);
assert(((unsigned int)(void *)byte_mask) & 3 == 0);
for (i = 0; i < (10+3)/4; i++) {
((unsigned int *)(byte_array))[i] &= ((unsigned int *)(byte_mask))[i];
}
这比逐字节处理快得多。
(请注意,这是就地突变;如果您还想保留原始byte_array,则显然需要将结果存储在另一个数组中。)
\#define CHAR_ARRAY_SIZE (10)
\#define INT_ARRAY_SIZE ((CHAR_ARRAY_SIZE/ (sizeof (unsigned int)) + 1)
typedef union _arr_tag_ {
char byte_array [CHAR_ARRAY_SIZE];
unsigned int int_array [INT_ARRAY_SIZE];
} arr_tag;
现在是用于掩码的int_array。这可能适用于32位和64位处理器。
arr_tag arr_src, arr_result, arr_mask;
for (int i = 0; i < INT_ARRAY_SIZE; i ++) {
arr_result.int_array [i] = arr_src.int_array[i] & arr_mask.int_array [i];
}
试试这个,代码看起来也很简洁。