Здравствуйте, CreatorCray, Вы писали:
CC>Здравствуйте, 0xCAFEDEAD, Вы писали:
CAF>>А какое решение быстрее (я слабо знаком с оптимизациями компиляторов, поэтому любые комменты от опытных тов приветствуются)
CC>Как правило компилятор всё равно преобразует кашу с индексами в адресную арифметику.
с одним итератором, а на двумя
CC>Ради интереса скормил код онлайн компилеру https://godbolt.org/ x86-64 gcc (trunk) -O3
CC>1.NuzhnyАвтор: Nuzhny
Дата: 10.10.18
, малость адаптирован чтоб таки скомпилить
CC>CC>#include <algorithm>
CC>void revert(char* first, char* last)
CC>{
CC> while ((first != last) && (first != --last)) {
CC> std::iter_swap (first++, last);
CC> }
CC>}
CC>
CC>2.RussianFellowАвтор: RussianFellow
Дата: 10.10.18
, для честности вынес strlen наружу как параметр
CC>CC>#include <stddef.h>
CC>void revert(char* s, size_t n)
CC>{
CC> for (auto i=0; i<n/2; i++)
CC> {
CC> auto c = s[i];
CC> s[i] = s[n-1-i];
CC> s[n-1-i] = c;
CC> }
CC>}
CC>
CC>Итого:
CC>1.
CC>CC>revert(char*, char*):
CC> cmp rdi, rsi
CC> jne .L3
CC> jmp .L1
CC>.L6:
CC> add rdi, 1
CC> movzx edx, BYTE PTR [rsi]
CC> movzx eax, BYTE PTR [rdi-1]
CC> mov BYTE PTR [rdi-1], dl
CC> mov BYTE PTR [rsi], al
CC> cmp rsi, rdi
CC> je .L1
CC>.L3:
CC> sub rsi, 1
CC> cmp rsi, rdi
CC> jne .L6
CC>.L1:
CC> ret
CC>
CC>2.
CC>CC>revert(char*, unsigned long):
CC> mov rdx, rsi
CC> shr rdx
CC> je .L1
CC> lea rax, [rdi-1+rsi]
CC> lea rsi, [rdi+rdx]
CC>.L4:
CC> movzx ecx, BYTE PTR [rax]
CC> movzx edx, BYTE PTR [rdi]
CC> add rdi, 1
CC> sub rax, 1
CC> mov BYTE PTR [rdi-1], cl
CC> mov BYTE PTR [rax+1], dl
CC> cmp rdi, rsi
CC> jne .L4
CC>.L1:
CC> ret
CC>
CC>Забавно что если взять другие компиляторы то 1й вариант меняется незначительно, а вот второй генерит вот такой вот пц:
CC>Clang (trunk) -O3
CC>CC>revert(char*, unsigned long): # @revert(char*, unsigned long)
CC> mov rcx, rsi
CC> shr rcx
CC> je .LBB0_6
CC> mov r8d, ecx
CC> and r8d, 1
CC> cmp rcx, 1
CC> jne .LBB0_7
CC> xor ecx, ecx
CC> test r8, r8
CC> jne .LBB0_5
CC> jmp .LBB0_6
CC>.LBB0_7:
CC> lea rdx, [rdi + 1]
CC> lea r11, [rdi + rsi]
CC> add r11, -1
CC> mov r9, r8
CC> sub r9, rcx
CC> xor ecx, ecx
CC>.LBB0_8: # =>This Inner Loop Header: Depth=1
CC> movzx r10d, byte ptr [rdx - 1]
CC> movzx eax, byte ptr [r11 + rcx]
CC> mov byte ptr [rdx - 1], al
CC> mov byte ptr [r11 + rcx], r10b
CC> movzx r10d, byte ptr [rdx]
CC> movzx eax, byte ptr [r11 + rcx - 1]
CC> mov byte ptr [rdx], al
CC> mov byte ptr [r11 + rcx - 1], r10b
CC> add rdx, 2
CC> add rcx, -2
CC> cmp r9, rcx
CC> jne .LBB0_8
CC> neg rcx
CC> test r8, r8
CC> je .LBB0_6
CC>.LBB0_5:
CC> mov r8b, byte ptr [rdi + rcx]
CC> mov rdx, rcx
CC> not rdx
CC> add rdx, rsi
CC> mov al, byte ptr [rdi + rdx]
CC> mov byte ptr [rdi + rcx], al
CC> mov byte ptr [rdi + rdx], r8b
CC>.LBB0_6:
CC> ret
CC>
CAF>>Ну и конечно на десерт, можно ли еще быстрее?
CC>Тут скорее не про быстрее стоит вести речь а про вменяемее.
Я имел ввиду именно быстрее. Допустим — это критичная функция для приложения (ну так надо этому злобному бизнесу).
т.е. не до красоты — пиши что хочешь, но выдай результат
CC>>>Из моего опыта — любители индексов в массе пишут спагетти код.
CAF>>Это мнение субъективное Спорить с таким утверждением бессмысленно.
CC>Ну так там так и написано "Лично я увидев в этой задаче индексы..."