在内存中排序值时重新分配最有效的方法?

时间:2014-07-20 13:39:47

标签: c malloc memcpy realloc

我分配了32个字节的连续内存(使用malloc)来保存8个连续的32位值。在对这段内存执行某些任务后,这些值的布局如下:

+---+---+---+---+---+---+---+---+
| d |   |   |   |   | a | b | c |
+---+---+---+---+---+---+---+---+

注意那里有一个洞?不再需要这些值,可以忽略这些值。这个洞总是是主要分配的一半,并且总是连续的。

重新分配这段内存的最有效和最快速的方法是什么,同时重新排序这些值?

+---+---+---+---+
| a | b | c | d |
+---+---+---+---+

任何建议都会有所帮助。

4 个答案:

答案 0 :(得分:0)

我会编写最简单的代码,使编译器可以轻松优化。一个好的编译器(甚至是坏的编译器,TBH)有更好的机会为我所使用的平台提供最快的组装。

因此,例如(为了简洁而排除了malloc / realloc错误检查):

uint32_t *buf = malloc(32);

// your operations here

buf[3] = buf[0];
buf[0] = buf[5];
buf[1] = buf[6];
buf[2] = buf[7];

// optional obviously, waste of time if that 16 bytes isn't a dealbreaker
buf = realloc(buf, 16);     

答案 1 :(得分:-1)

uint32_t *values;
if(offset == 0)
{
    values[0] = values[4];
    values[1] = values[5];
    values[2] = values[6];
    values[3] = values[7];
}
else if(offset == 1)
{
    values[3] = values[0];
    values[0] = values[5];
    values[1] = values[6];
    values[2] = values[7];
}
else if(offset == 2)
{
    values[2] = values[0];
    values[3] = values[1];
    values[0] = values[6];
    values[1] = values[7];
}
else if(offset == 3)
{
    values[3] = values[2];
    values[2] = values[1];
    values[1] = values[0];
    values[0] = values[7];
}

我知道,这是一个非常“愚蠢”的解决方案 但是所有内容都包含一个具有可变参数的memmove 就速度而言,我不会接近任何地方(并且模数......呃,是的。)

答案 2 :(得分:-1)

假设整个数组中的偶数个32位值(并且8是偶数),则类似下面的内容应该有效:

#include <string.h>
#include <stdint.h>

#include <stdio.h>

void re_sort_buffer(uint32_t *arr, size_t head_len, size_t hole_len, size_t tail_len) {
    memmove(arr+hole_len-head_len, arr, head_len*sizeof *arr); // see below
    memcpy(arr, arr+head_len+hole_len, tail_len*sizeof *arr);
}

int main(void) {
    uint32_t test[] = { 'b', 'c', 'd', '*', '*', '*', '*', 'a' };
    re_sort_buffer(test, 3, 4, 1);
    for(size_t i=0; i < 3+4+1; ++i) printf("'%c' ", test[i]);
    putchar('\n');
}

输出:

'a' 'b' 'c' 'd' '*' '*' '*' 'a' 

您可能希望对re_sort_buffer的某些参数进行硬编码或传递不同的参数等。

Iff hole_len - head_lenhead_len(相当于iff hole_len÷2(在您的情况下为2)≥head_len),您可以避免使用memmove改为使用memcpy;否则,我没有看到更好的方法。也许在这种情况下使用临时缓冲区会更好;我认为,一切都将是特定于平台的。

HTH

答案 3 :(得分:-1)

根据mafso的回答,我使用一个memmove和一个memcpy结束了此解决方案。

开始:

+---+---+---+---+---+---+---+---+
| d |   |   |   |   | a | b | c |
+---+---+---+---+---+---+---+---+

memmove右边的第一个元素:

+---+---+---+---+---+---+---+---+
| d |   |   | d |   | a | b | c |
+---+---+---+---+---+---+---+---+

memcpy结尾处的元素:

+---+---+---+---+---+---+---+---+
| a | b | c | d |   | a | b | c |
+---+---+---+---+---+---+---+---+

然后realloc缩短:

+---+---+---+---+
| a | b | c | d |
+---+---+---+---+

简单和简介非常快。