为什么模板元编程的效率反倒低下了——使用blitz的问题

flyincosmic 2004-11-25 03:28:13
最近学组合数学,做了一个关于生成gray码的习题,经典的算法我想不用多写了吧,
但是我观察了它的特点,任意大于2阶的n阶gray码,它的第一列总是上一半为0,下一半为1,而去掉第一列,剩下矩阵的上半部分总是n-1阶gray码,下半部分与之是经相对称的,如下:
为清晰,我把n阶gray码的矩阵分为两部分。
0, 0, 0
0, 0, 1
0, 1, 1
0, 1, 0

1, 1, 0
1, 1, 1
1, 0, 1
1, 0, 0

我认为这样的特点,正应适合用模板来解决,于是写了下面的程序,矩阵生成使用了blitz,可是测试效率,却几乎总是比经典算法慢了近50倍,不知是什么原因,恳请指教。下附程序
...全文
430 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
goodluckyxl 2004-12-16
  • 打赏
  • 举报
回复
模板的编译时期求值是一个好方法
但是不能对于参数传递地址否则
编译器必须要为他开辟空间再一步一步求解
使用enum枚举如同字符串常量一样 是不要分配空间的
但是其他的一看到地址传递
编译器马上确定他类型及大小分配空间
非常复杂
如果仅仅对于常量的求解放到编译期求解是很好的办法
但是一旦出现调用非常量地址传递后 就不好了
flyincosmic 2004-12-14
  • 打赏
  • 举报
回复
可是对于grayarray,它实际上是blitz的一个二维数组类型,前面已经typedef了。
谢谢你,我明白了,或者也许明白了,编译期求值的只是针对构造语句,而在构造过程中,数组并不需要预先求值,只是构造了一堆空数组,,当然第一个是实在的,等到运行期在一个一个地递归求出来,也就是说他求出了从2到n的所有结果,而后者只求了一个结果,当然慢很多就不奇怪了.
是否如此,欢迎讨论。
flyincosmic 2004-12-14
  • 打赏
  • 举报
回复
我要是写成(ROW, COL)就该比较清楚了,意思不言自明,就是构造一个gray码的n*2n矩阵
luclululu 2004-12-13
  • 打赏
  • 举报
回复
申明一下,我说的类的构造函数是指的T grayArray(ROW, NUM);上面写得有点含混,希望将意思表达清楚了:)
luclululu 2004-12-13
  • 打赏
  • 举报
回复
个人认为,模板递归中如果涉及到类的话,一步一步分析,那么实例化这个模板的实例的对象的时候,类的构造函数等需要调用,而构造函数等的调用是在执行期里实现的,所以虽然从特化的最初始类开始一直到最终的类,每个类都是一样的代码,但是由于涉及到构造函数的问题,所以每个类都会被实现出来,然后在执行期的时候再把每个类的result一个一个的往上传递到最终类,这就形成了执行期递归。虽然最终用户看到的是一个最终类,但是实际上内存中每个类都有,而且操作也是一步一步地在执行,没有在编译期处理中占到任何便宜,如果要避免这种情况,只有选择没有构造函数的实现方法,如何实现我也不知道,但是就这个问题而言,你那样写效率肯定是低的:)
yjh1982 2004-12-08
  • 打赏
  • 举报
回复
模版的使用会加大编译器的优化难度.


北极猩猩 2004-12-08
  • 打赏
  • 举报
回复
关键是模版的递归应该是在编译器执行的,而你的代码是在执行期进行递归,当然会影响运行效率
flyincosmic 2004-12-08
  • 打赏
  • 举报
回复
如何使它在编译期执行呢
flyincosmic 2004-12-04
  • 打赏
  • 举报
回复
模板本来是用递归的,不这样那又如何解呢
北极猩猩 2004-12-03
  • 打赏
  • 举报
回复
你的模板结果是递归计算出来的啊,并没有在编译时完成,肯定会慢的
hellwolf 2004-12-03
  • 打赏
  • 举报
回复
强,有空看看
勉励前行 2004-12-01
  • 打赏
  • 举报
回复
如果不能在編譯期計算出結果,你的模板算法就變成的遞歸計算。當然比傳統算法用迭代計算慢。
flyincosmic 2004-12-01
  • 打赏
  • 举报
回复
我觉得静态方法应该可以在编译期得出结果,这个程序当然有问题,可问题在哪儿
cxjddd 2004-11-30
  • 打赏
  • 举报
回复
会不会是你使用不当?还有你的测试似乎不公正:)
laomai 2004-11-30
  • 打赏
  • 举报
回复
强,等我喊人来看看,呵呵
flyincosmic 2004-11-25
  • 打赏
  • 举报
回复
/**
* 主程序
*
*/
#include "blitzarray.h"
#include "windows.h"

int main()
{
const int N = 20;
DWORD startTime;
startTime=timeGetTime();
graycode<N,grayArray_Type>::result();
cout<<"耗时 :"<<(timeGetTime() - startTime)<<"毫秒"<<endl;


startTime=timeGetTime();
gen_GrayCode(N);
cout<<"耗时 :"<<(timeGetTime() - startTime)<<"毫秒"<<endl;

}
flyincosmic 2004-11-25
  • 打赏
  • 举报
回复
/**
* 程序的头文件,包含经典算法与模板算法
*
*/

#include "fstream"
#include "iostream"
#include "blitz/array.h"

using namespace std;
using namespace blitz;

typedef Array<int, 2> grayArray_Type;
typedef Array<int, 1> colArray_Type;

//gray码模板
template <int NUM,typename T>
struct graycode
{
public:
enum {ROW = 2<<(NUM-1)};
static T result()
{
T grayArray(ROW, NUM);
int half = ROW>>1;
grayArray(Range(0, half-1), 0) = 0;
grayArray(Range(half, ROW-1), 0) = 1;
grayArray(Range(0, half-1), Range(1, NUM-1)) = graycode<NUM-1,T>::result();
grayArray(Range(ROW-1, half, -1), Range(1, NUM-1)) = graycode<NUM-1,T>::result();
return grayArray;
}
};

//特化版本
template <typename T>
struct graycode<1, T>
{
public:
enum{ ROW = 2 };
static T result()
{
T grayArray(ROW, 1);
grayArray(0,0) = 0;
grayArray(0,1) = 1;
return grayArray;
}
};


/**
*
*经典算法 矩阵中行元素按照a(n-1), a(n-2),……a(1), a(0)的顺序排列
*/

//判定当前行所有元素和的奇偶性
int Odd(colArray_Type arr)
{
int i = 0;
for(int j=0; j<arr.rows(); j++)
i+=arr(j);
return i%2;
};

//查找行元素和为奇时的j,使 对于所有的j>i,a(i)==0,返回j+1,
int findElement(colArray_Type arr)
{
int j = arr.rows()-1;
while(arr(j)==0 && j>=0)
{
j--;
}
return --j;
}

//输出gray码
grayArray_Type gen_GrayCode(int NUM)
{
int ROW = 2<<(NUM-1);
grayArray_Type grayArray(ROW, NUM); //建立gray码数组
grayArray(0, Range::all()) = 0; //第一行置0
for(int i=1; i<ROW; i++)
{
grayArray(i, Range::all()) = grayArray(i-1, Range::all()); //复制前一行
colArray_Type col = grayArray(i, Range::all());
if(0==Odd(col))
{
grayArray(i, NUM-1) = (grayArray(i-1, NUM-1)+1)%2; //行之和为奇,改变末位值
}
else //改变j+1位的值
{
int place = findElement(col);
if(place==NUM)
return grayArray;
grayArray(i, place) = (++grayArray(i, place))%2;
}
}
return grayArray;
}

24,855

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧