SORU
30 Mayıs 2010, Pazar


Daha verimli nedir? Meydanı pow ile ya da kendisi ile çarpın?

Bu iki yöntem C daha verimli nedir? Ve hakkında:

pow(x,3)

vs

x*x*x // etc?

CEVAP
31 Mayıs 2010, PAZARTESİ


x*x*... vs küçük pow(x,i) i arasında performans farkı bu kodu kullanarak test ettim:

#include <cstdlib>
#include <cmath>
#include <boost/date_time/posix_time/posix_time.hpp>

inline boost::posix_time::ptime now()
{
    return boost::posix_time::microsec_clock::local_time();
}

#define TEST(num, expression) \
double test##num(double b, long loops) \
{ \
    double x = 0.0; \
\
    boost::posix_time::ptime startTime = now(); \
    for (long i=0; i<loops;   i) \
    { \
        x  = expression; \
        x  = expression; \
        x  = expression; \
        x  = expression; \
        x  = expression; \
        x  = expression; \
        x  = expression; \
        x  = expression; \
        x  = expression; \
        x  = expression; \
    } \
    boost::posix_time::time_duration elapsed = now() - startTime; \
\
    std::cout << elapsed << " "; \
\
    return x; \
}

TEST(1, b)
TEST(2, b*b)
TEST(3, b*b*b)
TEST(4, b*b*b*b)
TEST(5, b*b*b*b*b)

template <int exponent>
double testpow(double base, long loops)
{
    double x = 0.0;

    boost::posix_time::ptime startTime = now();
    for (long i=0; i<loops;   i)
    {
        x  = std::pow(base, exponent);
        x  = std::pow(base, exponent);
        x  = std::pow(base, exponent);
        x  = std::pow(base, exponent);
        x  = std::pow(base, exponent);
        x  = std::pow(base, exponent);
        x  = std::pow(base, exponent);
        x  = std::pow(base, exponent);
        x  = std::pow(base, exponent);
        x  = std::pow(base, exponent);
    }
    boost::posix_time::time_duration elapsed = now() - startTime;

    std::cout << elapsed << " ";

    return x;
}

int main()
{
    using std::cout;
    long loops = 100000000l;
    double x = 0.0;
    cout << "1 ";
    x  = testpow<1>(rand(), loops);
    x  = test1(rand(), loops);

    cout << "\n2 ";
    x  = testpow<2>(rand(), loops);
    x  = test2(rand(), loops);

    cout << "\n3 ";
    x  = testpow<3>(rand(), loops);
    x  = test3(rand(), loops);

    cout << "\n4 ";
    x  = testpow<4>(rand(), loops);
    x  = test4(rand(), loops);

    cout << "\n5 ";
    x  = testpow<5>(rand(), loops);
    x  = test5(rand(), loops);
    cout << "\n" << x << "\n";
}

Sonuçlar:

1 00:00:01.126008 00:00:01.128338 
2 00:00:01.125832 00:00:01.127227 
3 00:00:01.125563 00:00:01.126590 
4 00:00:01.126289 00:00:01.126086 
5 00:00:01.126570 00:00:01.125930 
2.45829e 54

Her pow hesaplamanın sonucu derleyici optimize değil emin olmam birikir unutmayın.

Eğer std::pow(double, double) sürümünü kullanıyorum, ve loops = 1000000l,.

1 00:00:00.011339 00:00:00.011262 
2 00:00:00.011259 00:00:00.011254 
3 00:00:00.975658 00:00:00.011254 
4 00:00:00.976427 00:00:00.011254 
5 00:00:00.973029 00:00:00.011254 
2.45829e 52

Bu Intel Core Duo Ubuntu 9.10 64 bit çalışıyor. -O2 optimizasyonu ile derlenmiş kullanarak gcc 4.4.1.

C, Evet x*x*x pow(double, int) aşırı yük yok çünkü pow(x, 3), daha hızlı olacak. C , kabaca aynı olacaktır. (Benim test metodolojisi varsayarsak doğrudur.)


Bu açıklamayı Bir Markm tarafından yapılan cevaben:

Bile using namespace std Yönerge yayınladı, eğer ikinci parametre pow int std::pow(double, int) aşırı yük <cmath> denir yerine ::pow(double, double) <math.h>.

Bu test kodu bu davranışı onaylar:

#include <iostream>

namespace foo
{

    double bar(double x, int i)
    {
        std::cout << "foo::bar\n";
        return x*i;
    }


}

double bar(double x, double y)
{
    std::cout << "::bar\n";
    return x*y;
}

using namespace foo;

int main()
{
    double a = bar(1.2, 3); // Prints "foo::bar"
    std::cout << a << "\n";
    return 0;
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Android Developers

    Android Deve

    9 Kasım 2007
  • DancingIsAPassion

    DancingIsAPa

    29 AĞUSTOS 2009
  • WOSU Public Media

    WOSU Public

    23 AĞUSTOS 2007