Da die Debatte in einem Vergleich der AndyProwl und Alon Lösung entwickelt hat, ich Ich habe die beiden Lösungen verglichen, und das Ergebnis hängt von der Anzahl der Argumente ab.
Kompilieren mit:
g++-4.7 -std=c++11 -Wall -Wextra -O3 main.cpp -o main -D_FIRST
Benchmarks die AndyProwl Lösung und Kompilieren mit:
g++-4.7 -std=c++11 -Wall -Wextra -O3 main.cpp -o main -D_SECOND
Benchmarks die Lösung Alon.
Hier ist das Programm des Benchmarks für 10 Argumente.
#include <iostream>
#include <chrono>
// Function 1 : with &&
template <typename Type>
inline bool f1(const Type& arg)
{
return arg;
}
template <typename Type, typename... Types>
inline bool f1(const Type& arg, const Types&... args)
{
bool arg1 = f1(arg);
bool arg2 = f1(args...);
return arg1 && arg2;
}
// Function 2 : with &
template <typename Type>
inline bool f2(const Type& arg)
{
return arg;
}
template <typename Type, typename... Types>
inline bool f2(const Type& arg, const Types&... args)
{
return f2(arg) & f2(args...);
}
// Benchmark
int main(int argc, char* argv[])
{
// Variables
static const unsigned long long int primes[10] = {11, 13, 17, 19, 23, 29, 31, 37, 41, 43};
static const unsigned long long int nbenchs = 50;
static const unsigned long long int ntests = 10000000;
unsigned long long int sum = 0;
double result = 0;
double mean = 0;
std::chrono::high_resolution_clock::time_point t0 = std::chrono::high_resolution_clock::now();
// Loop of benchmarks
for (unsigned long long int ibench = 0; ibench < nbenchs; ++ibench) {
// Initialization
t0 = std::chrono::high_resolution_clock::now();
sum = 0;
// Loop of tests
for (unsigned long long int itest = 1; itest <= ntests; ++itest) {
#ifdef _FIRST
sum += f1((itest+sum)%primes[0], (itest+sum)%primes[1], (itest+sum)%primes[2], (itest+sum)%primes[3], (itest+sum)%primes[4], (itest+sum)%primes[5], (itest+sum)%primes[6], (itest+sum)%primes[7], (itest+sum)%primes[8], (itest+sum)%primes[9]);
#endif
#ifdef _SECOND
sum += f2((itest+sum)%primes[0], (itest+sum)%primes[1], (itest+sum)%primes[2], (itest+sum)%primes[3], (itest+sum)%primes[4], (itest+sum)%primes[5], (itest+sum)%primes[6], (itest+sum)%primes[7], (itest+sum)%primes[8], (itest+sum)%primes[9]);
#endif
}
// Finalization
result = std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::high_resolution_clock::now()-t0).count();
mean += result;
std::cout<<"time = "<<result<<" (sum = "<<sum<<")"<<std::endl;
}
// End
std::cout<<"mean time = "<<mean/nbenchs<<std::endl;
return 0;
}
Mit 50 Benchmarks für jede Lösung mit einer bestimmten Anzahl von Argumenten ist die Dispersion sehr klein, und die mittlere Zeit über dieses Benchmarks ist ein zuverlässiger Indikator.
Meine erste Benchmark war mit der "richtigen" Anzahl von Argumenten, wo die Alon-Lösung schneller ist als die AndyProwl-Lösung.
Die endgültigen Ergebnisse sind hier:
So ist die AndyProwl Lösung in der Regel schneller als die Alon ist. So, jetzt kann ich deine Antwort bestätigen. Aber ich denke, dass der Unterschied so klein ist, dass es von Architektur/Compiler abhängig ist.
So:
- AndyProwl + 1 für die im Allgemeinen schnellere Lösung
- Alon + 1 für Ihre constexpr fertige Lösung
Wie über das Ersetzen '&&' mit '&'? – fredoverflow