2015-11-19 7 views
-1

В C++ 11, какой из них быстрее: max(a-b, b-a) или abs(a-b)?Что быстрее в C++ 11: max (a-b, b-a) или abs (a-b)?

+3

[Который быстрее?] (Http://ericlippert.com/2012/12/17/performance-rant/) – crashmstr

+0

какой компилятор вы используете? – thumbmunkeys

+6

Довольно бессмысленный вопрос. В зависимости от типов и компилятора и платформы есть много способов, которыми это может закончиться. – harold

ответ

4

Вы можете использовать godbolt.org, постоянную ссылку: https://goo.gl/QmxbDe

#include <algorithm> 
#include <cstdlib> 

int abs1(int a, int b) { 
    return abs(a-b); 
} 

int abs2(int a, int b) { 
    return std::max(a-b, b-a); 
} 

int abs3(int a, int b) { 
return a > b ? a - b : b - a; 
} 

int abs4(int a, int b) { 
return a == b ? a : (a > b ? a - b : b - a); 
} 

Результат для лязг-3,7 x86 с -O4:

abs1(int, int):        # @abs1(int, int) 
    subl %esi, %edi 
    movl %edi, %eax 
    negl %eax 
    cmovll %edi, %eax 
    retq 

abs2(int, int):        # @abs2(int, int) 
    movl %edi, %eax 
    subl %esi, %eax 
    subl %edi, %esi 
    cmpl %esi, %eax 
    cmovgel %eax, %esi 
    movl %esi, %eax 
    retq 

abs3(int, int):        # @abs3(int, int) 
    movl %esi, %eax 
    subl %edi, %eax 
    subl %esi, %edi 
    cmovlel %eax, %edi 
    movl %edi, %eax 
    retq 

abs4(int, int):        # @abs4(int, int) 
    movl %edi, %eax 
    subl %esi, %eax 
    jne .LBB3_2 
    movl %edi, %eax 
    retq 
.LBB3_2: 
    jg .LBB3_4 
    subl %edi, %esi 
    movl %esi, %eax 
.LBB3_4: 
    retq 

Очевидно, что abs от cstdlib будет быстрее для случайных чисел.

+0

код, созданный другими компиляторами, отличается и может привести к разным выводам. Только время, когда код, в фактическом объеме использования, даст реальный ответ. –

+0

@dau_same Все компиляторы делают почти тот же код. Я провел бенчмаркинг (используя тест Google), все варианты взяты около 2-3 мс. – vladon

+0

2-3 миллисекунды для нескольких инструкций, кажется, очень несовместимо. Кроме того, важно, как вы выполняете ваши тесты, вы вызываете одну и ту же функцию несколько раз? Вы называете abs2 сразу после abs1? Пропуски кэша потребуют больше времени в этом случае, чем время вычисления, которое у вас есть в любой из этих функций. –

1

Мое предположение:

макс:

2 substraction: a-b, b-a 
1 comparation: a-b>b-a ? a-b : b-a 

абс:

1 substraction: a-b 
1 comparation a-b>0 ? a-b : -(a-b) 

и сравните с 0 это проще, чем сравнивать два значения

Так что я бы сказал abs быстрее до a,b являются примитивными типами данных

+0

Вещь, помеченная как «1 сравнение [sic]», скрывает больше операций, если вы не хотите, чтобы abs был примитивным (что является справедливым предположением * иногда *, но вы, похоже, не делаете этого) – harold

+0

Хорошая заметка @harold – maskacovnik

+0

Почему 'a> b? a - b: b - a'? Или даже 'a == b? a: (a> b? a - b: b - a) '. – vladon

3

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

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

4

Время, как метрика, действительно полезно только в контексте изменений. Здесь вы ищете изменения, которые происходят через вычисления за более короткий промежуток времени, но, возможно, в конечном счете наиболее существенный вид изменения состояния, который может произойти, находится внутри нас. Жизнь на самом деле просто переживает время (которое в конечном счете связано с переменами), и это часто короче, чем мы хотим. Мы можем испытывать столько изменений за конечное время, поскольку конечное время означает конечные изменения.

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

Вот картина Джессики Альбы для иллюстрации:

enter image description here

Смежные вопросы