C++ 循环嵌套变量数组合的快速生成
我有以下代码,它为循环嵌套的变量生成数字/索引的组合C++ 循环嵌套变量数组合的快速生成,c++,performance,loops,c++11,C++,Performance,Loops,C++11,我有以下代码,它为循环嵌套的变量生成数字/索引的组合 #include <iostream> #include <array> template<size_t ... Rest> inline void index_generator() { constexpr int size = sizeof...(Rest); std::array<int,size> maxes = {Rest...}; std::array<
#include <iostream>
#include <array>
template<size_t ... Rest>
inline void index_generator() {
constexpr int size = sizeof...(Rest);
std::array<int,size> maxes = {Rest...};
std::array<int,size> a;
int i,j;
std::fill(a.begin(),a.end(),0);
while(1)
{
for(i = 0; i<size; i++) {
std::cout << a[i] << " ";
}
std::cout << "\n";
for(j = size-1 ; j>=0 ; j--)
{
if(++a[j]<maxes[j])
break;
else
a[j]=0;
}
if(j<0)
break;
}
}
int main()
{
index_generator<2,3,3>();
return 0;
}
这确实相当于
for (int i=0; i<2; ++i)
for (int j=0; j<3; ++j)
for (int k=0; i<3; ++k)
for(int i=0;i您可以使用所有维度的乘法的单个循环生成它,并使用模作为最终索引
#include <iostream>
#include <array>
template<size_t ... Rest>
inline void index_generator( ) {
constexpr int size = sizeof...( Rest );
std::array<int, size> maxes = { Rest... };
int total = 1;
for (int i = 0; i<size; ++i) {
total *= maxes[i];
}
for (int i = 0; i < total; ++i) {
int remaining = total;
for (int n = 0; n < size; ++n) {
remaining /= maxes[n];
std::cout << ( i / remaining ) % maxes[n] << " ";
}
std::cout << std::endl;
}
}
执行代码
{
PROFILE_SCOPE( Index1 )
index_generator1<200, 3, 400, 20>( );
}
{
PROFILE_SCOPE( Index2 )
index_generator2<200, 3, 400, 20>( );
}
{
PROFILE_SCOPE( Index3 )
index_generator3<200, 3, 400, 20>( );
}
递归模板似乎是个好主意。而且也证明了C++为什么是一种坏语言。但是一个很棒的想法。@ ZBMQ不怪语言,责备程序员。OP显示他特设的模板解决方案比简单的嵌套for循环产生更差的代码。谁的错?@ Matzi的解决方案确实比我所发布的慢得多。您的解决方案的真正问题是使用了两个除法
s,这消耗了太多的CPUcycles@TasamFarkie我没有对它进行基准测试,但是有两个除法应该不是问题吃与嵌套循环完全相同的东西。@TasamFarkie你是对的。请参阅上面编辑的答案。你有多少个嵌套循环?嵌套循环的数量没有限制。
#include <array>
// Original from the question
template<size_t ... Rest>
inline void index_generator1( ) {
constexpr int size = sizeof...( Rest );
std::array<int, size> maxes = { Rest... };
std::array<int, size> a;
int i, j;
std::fill( a.begin( ), a.end( ), 0 );
int x = 0;
while (1) {
for (i = 0; i < size; i++) {
x += a[i];
}
for (j = size - 1; j >= 0; j--) {
if (++a[j] < maxes[j])
break;
else
a[j] = 0;
}
if (j < 0)
break;
}
LOG( x )
}
// Initial try
template<size_t ... Rest>
inline void index_generator2( ) {
constexpr int size = sizeof...( Rest );
int x = 0;
std::array<int, size> maxes = { Rest... };
int total = 1;
for (int i = 0; i < size; ++i) {
total *= maxes[i];
}
for (int i = 0; i < total; ++i) {
int remaining = total;
for (int n = 0; n < size; ++n) {
remaining /= maxes[n];
x += ( i / remaining ) % maxes[n];
}
}
LOG(x)
}
// Recursive templates
template <int... Args>
struct Impl;
template <int First, int... Args>
struct Impl<First, Args...>
{
static int Do( int sum )
{
int x = 0;
for (int i = 0; i < First; ++i) {
x += Impl<Args...>::Do( sum + i );
}
return x;
}
};
template <>
struct Impl<>
{
static int Do( int sum )
{
return sum;
}
};
template <int... Args>
void index_generator3( )
{
LOG( Impl<Args...>::Do( 0 ) );
}
{
PROFILE_SCOPE( Index1 )
index_generator1<200, 3, 400, 20>( );
}
{
PROFILE_SCOPE( Index2 )
index_generator2<200, 3, 400, 20>( );
}
{
PROFILE_SCOPE( Index3 )
index_generator3<200, 3, 400, 20>( );
}
[19:35:50]: 1485600000
[19:35:50]: 1485600000
[19:35:50]: 1485600000
[19:35:56]: PerCall(ms)
[19:35:56]: Index1 10.4016
[19:35:56]: Index2 75.3770
[19:35:56]: Index3 4.2299