我一直试图将我的代码从递归函数重写为迭代函数。
我想我会问,从递归代码到迭代代码,是否有任何关于/技巧/指导等的一般性思考......
e.g。我不能理解如何获得以下代码迭代,主要是因为递归中的循环进一步依赖并调用下一个递归。
struct entry
{
uint8_t values[8];
int32_t num_values;
std::array<entry, 256>* next_table;
void push_back(uint8_t value) {values[num_values++] = value;}
};
struct node
{
node* children; // +0 right, +1 left
uint8_t value;
uint8_t is_leaf;
};
void build_tables(node* root, std::array<std::array<entry, 8>, 255>& tables, int& table_count)
{
int table_index = root->value; // root is always a non-leave, thus value is the current table index.
for(int n = 0; n < 256; ++n)
{
auto current = root;
// Recurse the the huffman tree bit by bit for this table entry
for(int i = 0; i < 8; ++i)
{
current = current->children + ((n >> i) & 1); // Travel to the next node current->children[0] is left child and current->children[1] is right child. If current is a leaf then current->childen[0/1] point to the root.
if(current->is_leaf)
tables[table_index][n].push_back(current->value);
}
if(!current->is_leaf)
{
if(current->value == 0) // For non-leaves, the "value" is the sub-table index for this particular non-leave node
{
current->value = table_count++;
build_tables(current, tables, table_count);
}
tables[table_index][n].next_table = &tables[current->value];
}
else
tables[table_index][n].next_table = &tables[0];
}
}
答案 0 :(得分:1)
由于tables
和table_count
始终引用相同的对象,您可以通过tables
和table_count
从{{{}的参数列表中获得较小的性能提升1}}将它们存储为临时结构的成员,然后执行以下操作:
build_tables
当然,这仅适用于您的编译器不够智能以自行进行此优化的情况。
唯一可以使这种非递归的方法就是自己管理堆栈。我怀疑这会比递归版本更快。
总而言之,我怀疑你的性能问题是递归。将三个引用参数推送到堆栈并调用一个函数我认为与你的函数相比是一个巨大的负担。