Преинкремент C ++ против постинкремента на указателе char * при присваивании значения - PullRequest
0 голосов
/ 11 сентября 2018

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

char * temp = "abc"; 
char c = 0; 

Теперь, если я хочу присвоить 'a' c и увеличить temp , чтобы теперь он указывал на 'b', я бы сделал это так:

c = *temp++; 

но предварительное увеличение должно быть быстрее, поэтому я подумал:

c = *temp; 
++temp;

но получается * temp ++ быстрее по моим измерениям.

Теперь я не совсем понимаю, почему и как, поэтому, если кто-то хочет просветить меня, пожалуйста, сделайте.

1 Ответ

0 голосов
/ 11 сентября 2018

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

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

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

# c = *temp++;
movq    temp(%rip), %rax
leaq    1(%rax), %rdx
movq    %rdx, temp(%rip)
movzbl  (%rax), %eax
movb    %al, c(%rip)

# c = *temp;
movq    temp(%rip), %rax
movzbl  (%rax), %eax
movb    %al, c(%rip)
# ++temp;
movq    temp(%rip), %rax
addq    $1, %rax
movq    %rax, temp(%rip)

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

Однако, при включении оптимизации это превращается в:

# c = *temp++;
movq    temp(%rip), %rax
leaq    1(%rax), %rdx
movq    %rdx, temp(%rip)
movzbl  (%rax), %eax
movb    %al, c(%rip)

# c = *temp;
# ++temp;
movq    temp(%rip), %rax
movzbl  (%rax), %edx
addq    $1, %rax
movq    %rax, temp(%rip)
movb    %dl, c(%rip)

Кромедругой порядок инструкций и выбор использования addq против leaq для приращения, между этими двумя нет реальной разницы.Если вы do получаете (измеримо) различную производительность между этими двумя, то это, вероятно, связано с конкретной архитектурой процессора (возможно, более оптимальным использованием конвейера, например.).

...