Доступ к элементам массива через указатель? - PullRequest
1 голос
/ 13 июля 2020

Снова на [] vs *:

void func(const instance* I, const float* in, float* out)
{
    for(int i=0;i<N; i++)
    {
        // some calculation goes here
        out[i] = ... in[i] * I.something[i] ... ;
    }
}

Довольно часто я обнаруживаю, что код подфункции написан таким образом, что массивы не ссылаются на [], но дополнительные указатели вводится, например:

void func(const instance* I, const float* in, float* out)
{
    const float* inp = in;
    float* outp = out;
    float* s = I->something;

    for(int i=0;i<N; i++)
    {
        // some calculation goes here
        outp++ = ... inp++ * s++ ... ;
    }
}

Какова основная причина этого: удобочитаемость, производительность или что-то еще? Влияет ли это на производительность?

1 Ответ

2 голосов
/ 13 июля 2020

Какова основная причина этого: удобочитаемость, производительность или что-то еще? Влияет ли это на производительность?

  1. Обычно мы вводим новые переменные, если хотим сохранить исходные параметры, которые будут использоваться позже в функции.

например:

char *mystrcpy(char *dest, const char *src)
{
    char *workdest = dest;   // temp variable to be used instead of dest.
    while((*workdest++ = *src++));
    return dest;
}

Обычно это не влияет на производительность, если вы используете оптимизирующий компилятор (и включаете оптимизацию)

Введение новых (теоретически не необходимых переменных) может помочь разделить сложный лог c на более мелкие, более простые в обслуживании детали. Это также обычно не влияет на производительность, поскольку компиляторы обычно достаточно хорошо оптимизируют его. то же самое.

пример:

int *reverse(int *arr, size_t size)
{
    int *end, *saved = arr;
    if(arr && size > 1)
    {
        end = arr + size - 1;
        while(end > arr)
        {
            int tmp = *arr;
            *arr++ = *end;
            *end-- = tmp;
        }
    }
    return saved;
}

int *reverse1(int *arr, size_t num)
{
    if(arr && num > 1)
    {
        for(size_t i = 0; i < num/2; i++) 
        {
            int  temp;
            temp=arr[i];
            arr[i] = arr[num-(i+1)];
            arr[num-(i+1)]=temp;
        }
    }
    return arr;
}

и полученный код:

reverse:
        mov     r8, rdi
        test    rdi, rdi
        je      .L2
        cmp     rsi, 1
        jbe     .L2
        lea     rax, [rdi-4+rsi*4]
        cmp     rdi, rax
        jnb     .L2
        mov     rdx, rdi
.L3:
        mov     ecx, DWORD PTR [rdx]
        mov     esi, DWORD PTR [rax]
        add     rdx, 4
        sub     rax, 4
        mov     DWORD PTR [rdx-4], esi
        mov     DWORD PTR [rax+4], ecx
        cmp     rdx, rax
        jb      .L3
.L2:
        mov     rax, r8
        ret
reverse1:
        mov     r8, rdi
        test    rdi, rdi
        je      .L18
        cmp     rsi, 1
        jbe     .L18
        lea     rdx, [rdi-4+rsi*4]
        shr     rsi
        mov     rax, rdi
        lea     rdi, [rdi+rsi*4]
.L15:
        mov     esi, DWORD PTR [rdx]
        mov     ecx, DWORD PTR [rax]
        add     rax, 4
        sub     rdx, 4
        mov     DWORD PTR [rax-4], esi
        mov     DWORD PTR [rdx+4], ecx
        cmp     rax, rdi
        jne     .L15
.L18:
        mov     rax, r8
        ret

https://godbolt.org/z/qTG59h

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...