最有效地找到三个ints

问题描述 投票:0回答:15

要找到最大的要精确查看3个INT,不再是。您正在查看6个比较3。您应该可以在3和2中进行比较。
int ret = max(i,j);
ret = max(ret, k);
return ret;

c++ performance max min
15个回答
29
投票

result = i if j > result: result = j if k > result: result = k return result



19
投票
return i > j? (i > k? i: k): (j > k? j: k);

两次比较,不使用瞬态临时堆栈变量...



14
投票
http://ideone.com/jzeqztlj

(0.40s)

chris的解决方案:
int ret = max(i,j);
ret = max(ret, k);
return ret;


8
投票
(0.39s)

INGACIO VAZQUEZ-ABRAMS的解决:

result = i; if (j > result) result = j; if (k > result) result = k; return result;

http://ideone.com/jkbtkgxi
(0.40s)

查尔斯·布雷塔纳(Charles Bretana):

return i > j? (i > k? i: k): (j > k? j: k);

Http://ideone.com/kyl0spuz
(0.40s)

对于这些测试,所有解决方案所需的时间比其他解决方案的时间要在3%之内。您要优化的代码非常短。即使您能够从中挤出1个指令,也不太可能在整个程序中产生巨大的差异(现代编译器可能会捕捉到这么小的优化)。花时间在其他地方。

Edit:

更新了测试,事实证明它仍在优化其部分。希望已经不复存在了。

对于这样的问题,

没有替代您知道您的优化编译器在做什么以及硬件上可用的内容。 如果您拥有的基本工具是二进制比较或二进制最大值,则需要进行两个比较或麦克斯(Max)。 我更喜欢Ignacio的解决方案:

result = i; if (j > result) result = j; if (k > result) result = k; return result;

由于在常见的现代英特尔硬件上,编译器将发现仅发射两个比较和两个指令非常容易,这在i-cache上施加了较小的负载,而在分支预测器上的压力较小,而不是条件分支。 (此外,代码清晰易于阅读。)如果您使用的是X86-64,则编译器甚至将所有内容都保存在寄存器中。

注意,您将很难按下将此代码嵌入程序,您的选择会有所作为...


6
投票
我喜欢消除有条件的跳跃作为一种智力练习。这是否对性能有任何可测量的影响,我不知道:)

cmov this Twiddling只是为了娱乐,

#include <iostream> #include <limits> inline int max(int a, int b) { int difference = a - b; int b_greater = difference >> std::numeric_limits<int>::digits; return a - (difference & b_greater); } int max(int a, int b, int c) { return max(max(a, b), c); } int main() { std::cout << max(1, 2, 3) << std::endl; std::cout << max(1, 3, 2) << std::endl; std::cout << max(2, 1, 3) << std::endl; std::cout << max(2, 3, 1) << std::endl; std::cout << max(3, 1, 2) << std::endl; std::cout << max(3, 2, 1) << std::endl; }

解决方案可能会更快。

确定这是否是最有效的,但可能是最有效的,而且绝对较短:

cmov

在C ++中找到最大或最小数字的最大或最低数字的最简单方法是: -

int maximum = max( max(i, j), k);

4
投票
Https://godbolt.org/z/j1km97

)一样高效:

int a = 3, b = 4, c = 5;
int maximum = max({a, b, c});

int a = 3, b = 4, c = 5;
int minimum = min({a, b, c});

与GCC相似,而MSVC则与一个循环混乱。


提出了将其包括在N2485下的C ++库中的建议。该提案很简单,因此我在下面包含了有意义的代码。显然,这是假定变异模板

3
投票
mov eax, dword ptr [rsp + 8] mov ecx, dword ptr [rsp + 4] cmp eax, ecx cmovl eax, ecx mov ecx, dword ptr [rsp] cmp eax, ecx cmovl eax, ecx

template < typename T >
const T & max ( const T & a )
{ return a ; }

template < typename T , typename ... Args >
const T & max( const T & a , const T & b , const Args &... args )
{ return  max ( b > a ? b : a , args ...); }

2
投票

我在“最有效的”中思考您正在谈论性能,试图不浪费计算资源。但是您可能是指编写较少的代码行或源代码的可读性。我在下面提供一个示例,您可以评估是否发现有用的东西,或者是否喜欢收到答案中的另一个版本。
public int maximum(int a,int b,int c){
    int max = a;
    if(b>max)
        max = b;
    if(c>max)
        max = c;
    return max;
}

/* Java version, whose syntax is very similar to C++. Call this program "LargestOfThreeNumbers.java" */ class LargestOfThreeNumbers{ public static void main(String args[]){ int x, y, z, largest; x = 1; y = 2; z = 3; largest = x; if(y > x){ largest = y; if(z > y){ largest = z; } }else if(z > x){ largest = z; } System.out.println("The largest number is: " + largest); } }

我使用这种方式,花了0.01秒
#include<stdio.h>
int main()
{
    int a,b,c,d,e;
    scanf("%d %d %d",&a,&b,&c);
    d=(a+b+abs(a-b))/2;
    e=(d+c+abs(c-d))/2;
    printf("%d is Max\n",e);
    return 0;
}

或这个

1
投票

在3个数字中找到最大的最有效方法是使用最大函数。这是一个小例子:

0
投票
如果您有C ++ 11,那么您可以按照以下方式进行操作:

0
投票

如果您有兴趣使用函数,以便可以轻松地调用它多次,以下是代码:

int main() {
   int x = 3, y = 4, z = 5;
   cout << std::max({x, y, z}); << endl;
   return 0;
}

0
投票
您可以使用的小功能:
using namespace std;

int test(int x, int y, int z) { //created a test function

    //return std::max({x, y, z}); //if installed C++11
    return max(x, max(y, z));
}

int main() {
    cout << test(1, 2, 3) << endl;
    cout << test(1, 3, 2) << endl;
    cout << test(1, 1, 1) << endl;
    cout << test(1, 2, 2) << endl;
    return 0;
}

0
投票

为了娱乐:
int max3(int a, int b, int c=INT_MIN) {
    return max(a, max(b, c));
}

也有效,但在godbolt.org上产生了很多说明,表明使用BIT OPS并不是表现的保证:
unsigned int max3(const unsigned int A, const unsigned int B, const unsigned int C) {
    return ((-int((A<C)&(B<C)))&C) 
         | ((-int((A<B)&(C<B)))&B) 
         | ((-int((B<A)&(C<A)))&A));

0
投票

C#在3位数字之间找到最大和最小的数字

max3(unsigned int, unsigned int, unsigned int):
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-4], edi
        mov     DWORD PTR [rbp-8], esi
        mov     DWORD PTR [rbp-12], edx
        mov     edx, DWORD PTR [rbp-4]
        mov     eax, DWORD PTR [rbp-8]
        cmp     edx, eax
        cmovnb  eax, edx
        cmp     eax, DWORD PTR [rbp-12]
        setb    al
        movzx   eax, al
        imul    eax, DWORD PTR [rbp-12]
        mov     ecx, eax
        mov     edx, DWORD PTR [rbp-4]
        mov     eax, DWORD PTR [rbp-12]
        cmp     edx, eax
        cmovnb  eax, edx
        cmp     eax, DWORD PTR [rbp-8]
        setb    al
        movzx   eax, al
        imul    eax, DWORD PTR [rbp-8]
        or      ecx, eax
        mov     edx, DWORD PTR [rbp-8]
        mov     eax, DWORD PTR [rbp-12]
        cmp     edx, eax
        cmovnb  eax, edx
        cmp     eax, DWORD PTR [rbp-4]
        setb    al
        movzx   eax, al
        imul    eax, DWORD PTR [rbp-4]
        or      eax, ecx
        pop     rbp
        ret
x:
        .zero   4
__static_initialization_and_destruction_0():
        push    rbp
        mov     rbp, rsp
        mov     edx, 6
        mov     esi, 1
        mov     edi, 3
        call    max3(unsigned int, unsigned int, unsigned int)
        mov     DWORD PTR x[rip], eax
        nop
        pop     rbp
        ret
_GLOBAL__sub_I_max3(unsigned int, unsigned int, unsigned int):
        push    rbp
        mov     rbp, rsp
        call    __static_initialization_and_destruction_0()
        pop     rbp
        ret

================================================ ================

static void recorrectFindSmallestNumber()
{
int x = 30, y = 22, z = 11;
if (x < y)
{
if (x < z)
{
Console.WriteLine("X is Smaller Numebr {0}.", x);
}
else
{
Console.WriteLine("z is Smaller Numebr {0}.", z);
}
}
else if (x > y)
{
if (y < z)
{
Console.WriteLine("y is Smaller number.{0}", y);
}
else
{
Console.WriteLine("z is Smaller number.{0}", z);
}
}
 else
{

}
}

static void recorrectFindLargeNumber()
{
int x, y, z;
Console.WriteLine("Enter the first number:");
x = int.Parse(Console.ReadLine());
Console.WriteLine("Enter the second number:");
y = int.Parse(Console.ReadLine());
Console.WriteLine("Enter the third nuumnber:");
z = int.Parse(Console.ReadLine());
if (x > y)
{
if (x > z)
{
Console.WriteLine("X is Greater numbaer: {0}.", x);
}
else
{
Console.WriteLine("Z is greatest number: {0}.", z);
}
}
else if (x < y)
{
if (y > z)
{
Console.WriteLine("y is Greater Number: {0}", y);
}
else 
{
Console.WriteLine("Z is Greater Number; {0}", z);                
}
}
else
{
                
}
}

0
投票

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.