C указатели по сравнению с прямым членским доступом для структур

Я, кажется, не забываю читать, что это применимо для некоторых более простых использований, но в усовершенствованных ситуациях это все еще неполно или зелено.

относительно того, является ли это применимым производством, я должен был бы сказать, что это зависит. Для некоторых людей они рады работать с ранней альфа-версией программного обеспечения для других любой вид программного обеспечения с открытым исходным кодом, неважно, насколько сформировавшийся шаг слишком далеко.

Вам решать для разграничивания, где Вы считаете целесообразным. Спросите себя, насколько очень важный сайт? Как время простоя влияло бы на бизнес. Каков худший сценарий случая, если ошибка действительно происходит?

, Если бы Вы создаете блог для себя и немногих других для чтения, я предположил бы, что это - готовое производство. Если Вы - lauching новый критически важный для бизнеса сайт, если бы часы время простоя были, то мог бы стоить тысяч, то, возможно, содержат некоторое время дольше.

10
задан starblue 26 August 2009 в 08:37
поделиться

9 ответов

В общем, я бы сказал, выбери первый вариант:

double LocalSpeed = MyGlobal.MaxSpeed;

Здесь на одно разыменование меньше (вы не находите указатель, а затем разыменовываете его, чтобы добраться до его местоположения). Его также проще и легче читать и поддерживать, поскольку вам не нужно создавать переменную-указатель в дополнение к структуре.

При этом я не думаю, что какая-либо разница в производительности, которую вы увидите, будет заметной, даже во встроенной системе. Оба будут иметь очень и очень быстрое время доступа.

20
ответ дан 3 December 2019 в 13:56
поделиться

Первый должен быть быстрее, так как он не требует разыменования указателя. Опять же, это верно для систем на базе x86, но не уверен для других.

на x86 первый переводится примерно так

mov eax, [address of MyGlobal.MaxSpeed]

, а второй будет примерно так

mov ebx, [address of pMyGlobal] 
mov eax, [ebx+sizeof(int)] 
8
ответ дан 3 December 2019 в 13:56
поделиться

На вашей встроенной платформе, вполне вероятно, что архитектура оптимизирована таким образом, что это по сути промывка, и даже если бы это было не так, вы бы когда-либо заметили влияние на производительность, только если бы это было выполняется в очень плотном цикле.

Вероятно, существуют гораздо более очевидные области производительности вашей системы.

3
ответ дан 3 December 2019 в 13:56
поделиться
struct dataStruct
{
    double first;
    double second;
} data;

int main()
{
    dataStruct* pData = &data;

    data.first = 9.0;
    pData->second = 10.0;
}

Это результат сборки с использованием режима выпуска VS2008:

    data.first = 9.0;
008D1000  fld         qword ptr [__real@4022000000000000 (8D20F0h)] 

    pData->second = 10.0;
008D1006  xor         eax,eax 
008D1008  fstp        qword ptr [data (8D3378h)] 
008D100E  fld         qword ptr [__real@4024000000000000 (8D20E8h)] 
008D1014  fstp        qword ptr [data+8 (8D3380h)] 
3
ответ дан 3 December 2019 в 13:56
поделиться

Я полагаю, что если это вообще имеет значение, это будет зависеть от архитектуры.

1
ответ дан 3 December 2019 в 13:56
поделиться

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

1
ответ дан 3 December 2019 в 13:56
поделиться

В C не должно быть разницы или незначительного снижения производительности.

Учащимся C учат:

pMyGlobal->MaxSpeed == (*pMyGlobal).MaxSpeed

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

Если вы ищете оптимизацию производительности, я бы поискал в другом месте. Вы не сможете сэкономить достаточно циклов процессора с помощью такого рода микрооптимизации.

По стилистическим соображениям я предпочитаю нотацию Structure-Dot, особенно при работе с singleton-globals. Я считаю, что его читать намного проще.

1
ответ дан 3 December 2019 в 13:56
поделиться

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

0
ответ дан 3 December 2019 в 13:56
поделиться

дизассемблировать, дизассемблировать, дизассемблировать ...

В зависимости от строк кода, которые вы нам не показываете, возможно, что если ваш указатель несколько статичен, хороший компилятор узнает об этом и предварительно -вычислить адрес для обоих. Если у вас нет оптимизации, тогда все это обсуждение будет немым. Это также зависит от процессора, который вы используете, и то, и другое может выполняться с помощью одной инструкции в зависимости от процессора. Итак, я следую основным шагам оптимизации:

1) разобрать и изучить 2) время выполнения

Как упоминалось выше, хотя суть в том, что это может быть случай двух инструкций вместо одной, требующей одного такта, вы, вероятно, никогда не увидите. Качество вашего выбора компилятора и оптимизатора приведет к гораздо более значительным различиям в производительности, чем попытки настроить одну строку кода в надежде улучшить производительность. Смена компилятора может дать вам 10-20% в любом направлении, а иногда и больше. Как и изменение ваших флагов оптимизации, включение всего не делает код максимально быстрым, иногда -O1 работает лучше, чем -O3.

Понимание того, что производят эти две строки кода и как максимизировать производительность с помощью языка высокого уровня, приходит от компиляции для разные процессоры и дизассемблирование с использованием разных компиляторов. И что еще более важно, код вокруг рассматриваемых строк играет большую роль в том, как компилятор оптимизирует этот сегмент.

Используя чужой пример по этому вопросу:

typedef struct
{
    unsigned int first;
    unsigned int second;
} dataStruct;

dataStruct data;

int main()
{
    dataStruct *pData = &data;

    data.first = 9;
    pData->second = 10;

    return(0);
}

Используя gcc (не такой уж хороший компилятор), вы получите:

mov r2, #10
mov r1, #9
stmia   r3, {r1, r2}

] Итак, обе строки кода C объединены в одно хранилище, проблема здесь в примере, используемом в качестве теста. Две отдельные функции были бы немного лучше, но для этого нужно намного больше кода, а указатель должен указывать на какую-то другую память, чтобы оптимизатор не понимал, что это статический глобальный адрес, чтобы проверить это, вам нужно передать адрес в поэтому компилятор (ну, gcc) не может определить, что это статический адрес.

Или без оптимизаций, тот же код, тот же компилятор, нет разницы между указателем и прямым.

mov r3, #9
str r3, [r2, #0]

mov r3, #10
str r3, [r2, #4]

Это то, что вы ожидаете увидеть в зависимости от на компиляторе и процессоре, не может быть разницы. Для этого процессора, даже если тестовый код скрывал статический адрес указателя от функции, он все равно сводился бы к двум инструкциям. Если значение, хранящееся в элементе структуры, уже было загружено в регистр, тогда это была бы одна инструкция в любом случае, указательная или прямая.

Так что ответ на ваш вопрос не является абсолютным ... это зависит от обстоятельств. разобрать и протестировать.

2
ответ дан 3 December 2019 в 13:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: