Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/rest/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 树迭代器,你能进一步优化它吗?_C++_Optimization_Iteration_Binary Tree - Fatal编程技术网

C++ 树迭代器,你能进一步优化它吗?

C++ 树迭代器,你能进一步优化它吗?,c++,optimization,iteration,binary-tree,C++,Optimization,Iteration,Binary Tree,作为我最初关于这段代码的一小部分的问题的后续,我决定问一个后续问题,看看你是否能比我们目前提出的做得更好 下面的代码迭代二叉树(left/right=child/next)。我确实相信这里有一个条件更少的空间(downboolean)。最快的答案获胜 cnt语句可以是多个语句,因此让我们确保它只出现一次 child()和next()成员函数的速度大约是hasChild()和hasNext()操作的30倍 保持迭代为什么不是递归解决方案 void processTree (const BaseNo

作为我最初关于这段代码的一小部分的问题的后续,我决定问一个后续问题,看看你是否能比我们目前提出的做得更好

下面的代码迭代二叉树(left/right=child/next)。我确实相信这里有一个条件更少的空间(
down
boolean)。最快的答案获胜

  • cnt
    语句可以是多个语句,因此让我们确保它只出现一次
  • child()
    next()
    成员函数的速度大约是hasChild()和hasNext()操作的30倍

  • 保持迭代为什么不是递归解决方案

    void processTree (const BaseNodePtr &current, unsigned int & cnt )
    {
      cnt++;
    
      if (current->hasChild())
        processTree(current->child());
      if (current->hasNext())
        processTree(current->next());
    }
    
    既然
    shared\u ptr
    似乎是您的瓶颈,为什么不改进它呢?你在使用线程吗?如果没有,则取消定义符号
    BOOST\u的线程数。
    共享\u ptr
    引用计数由互斥锁保护,这可能是性能缓慢的原因


    为什么不将数据结构更改为不同时使用
    shared\ptr
    ?自己管理原始指针?也许可以使用
    作用域\u ptr
    替代?

    为什么不使用递归解决方案

    void processTree (const BaseNodePtr &current, unsigned int & cnt )
    {
      cnt++;
    
      if (current->hasChild())
        processTree(current->child());
      if (current->hasNext())
        processTree(current->next());
    }
    
    既然
    shared\u ptr
    似乎是您的瓶颈,为什么不改进它呢?你在使用线程吗?如果没有,则取消定义符号
    BOOST\u的线程数。
    共享\u ptr
    引用计数由互斥锁保护,这可能是性能缓慢的原因

    为什么不将数据结构更改为不同时使用
    shared\ptr
    ?自己管理原始指针?也许可以使用
    作用域\u ptr
    来代替?

    创建一个“nextvisit”函数,并继续调用该函数,以简化代码;接下来,对共享指针使用常量引用iso值语义。。。这可能会为您节省宝贵的共享ptr副本:

    // define the order of visitation in here
    BaseNodePtr& next( const BaseNodePtr& p ) {
        if( p->hasChild() ) return p->child();
        if( p->hasNext() ) return p->next();
        BaseNodePtr ancestor = p->parent();
        while( ancestor != 0 && !ancestor->hasNext() ) ancestor = ancestor->parent();
        return ancestor;
    }
    
    void processTree( const BaseNodePtr& p, unsigned int& cnt ) {
       while( p != NULL ) {
         ++cnt;
         p = next(p);
       }        
    }
    
    但为了可读性、清晰性、可维护性。。。看在上帝的份上,使用递归。除非你的堆栈不够大。

    创建一个“nextvisit”函数,并不断调用它,以简化代码;接下来,对共享指针使用常量引用iso值语义。。。这可能会为您节省宝贵的共享ptr副本:

    // define the order of visitation in here
    BaseNodePtr& next( const BaseNodePtr& p ) {
        if( p->hasChild() ) return p->child();
        if( p->hasNext() ) return p->next();
        BaseNodePtr ancestor = p->parent();
        while( ancestor != 0 && !ancestor->hasNext() ) ancestor = ancestor->parent();
        return ancestor;
    }
    
    void processTree( const BaseNodePtr& p, unsigned int& cnt ) {
       while( p != NULL ) {
         ++cnt;
         p = next(p);
       }        
    }
    
    但为了可读性、清晰性、可维护性。。。看在上帝的份上,使用递归。除非你的堆栈不够大。

    当回答以“不要那样做”来回避问题时,我讨厌。

    说有一种方法可以移除下壁。。。这真的会对执行时间产生真正的影响吗?我们讨论的是少量CPU操作和堆栈上的一些额外字节

    如果需要加快调用速度,请将重点放在加快child()和parent()调用上。否则你就是在浪费时间(伊莫霍)

    编辑: 也许可以遍历一次树(使用这个“慢”代码),然后按照所需的顺序在树中构建一个指针数组。稍后使用此“索引”

    我想说的是,我认为你从错误的角度来处理优化问题。

    当答案以“不要那样做”来回避这个问题时,我恨你。

    但我来了

    说有一种方法可以移除下壁。。。这真的会对执行时间产生真正的影响吗?我们讨论的是少量CPU操作和堆栈上的一些额外字节

    如果需要加快调用速度,请将重点放在加快child()和parent()调用上。否则你就是在浪费时间(伊莫霍)

    编辑: 也许可以遍历一次树(使用这个“慢”代码),然后按照所需的顺序在树中构建一个指针数组。稍后使用此“索引”


    我想说的是,我认为您从错误的角度进行优化。

    这里介绍了如何只调用一个递归调用,而不是两个递归调用:

    void processTree (const BaseNodePtr &current, unsigned int & cnt )
    {
      for(bool gotNext = true; gotNext; current = current->next()) { 
        cnt++;
        if (current->hasChild())
          processTree(current->child());
        gotNext = current->hasNext();
      }
    }
    

    下面是如何只调用一个递归调用而不是两个递归调用:

    void processTree (const BaseNodePtr &current, unsigned int & cnt )
    {
      for(bool gotNext = true; gotNext; current = current->next()) { 
        cnt++;
        if (current->hasChild())
          processTree(current->child());
        gotNext = current->hasNext();
      }
    }
    

    为了提高最终的速度,您需要对内存中的节点进行排序,以便它们按照访问顺序存储在连续块中

    e、 如果你有一棵树,定义如下

            1
           / \
          2   3
         / \  /\
        4   5 6 7
       /\    /  /\
      8  9  10 11 12
     / \           \
    13 14          15
    
    然后,如上所述的访问功能将按以下顺序访问节点

    1
     2
      4
       8
        13
        14
       9
      5
     3
      6
       10
      7
       11
       12
         15
    
    现在,如果您将内存中的节点排序为15个分配的连续块,并按照上面演示的顺序存储节点,那么您通常将访问具有“”的节点。这可以根据节点结构的大小提高缓存命中率,从而加快运行速度

    创建一种快速迭代的方法,只访问树中的所有节点一次,不递归

    unsigned int g_StackDepth = 0;
    BaseNodePtr* g_Stack[MAX_STACK_DEPTH];
    
    void processTree (BaseNodePtr root, unsigned int & cnt )
    {
        g_Stack[g_StackDepth++] = root;
        while( g_StackDepth > 0 )
        {
            BaseNodePtr curr = g_Stack[--g_StackDepth];
            cnt++;
    
            if ( curr->HasNext() )
            {
                g_Stack[g_StackDepth++] = curr->Next();
            }
    
    
            if ( curr->HasChild() )
            {
                g_Stack[g_StackDepth++] = curr->Child();
            }
    
        }
    }
    
    据我所知,结合上述订购,您应该可以获得最佳速度

    显然,这是有局限性的,因为您必须知道堆栈可以提前增长多大。尽管您可以通过使用std::vector来解决这个问题。然而,使用std::vector将消除上述迭代方法提供的所有优点


    希望对您有所帮助:)

    要想获得最高的速度,您需要做的是对内存中的节点进行排序,以便它们按照访问顺序存储在连续块中

    e、 如果你有一棵树,定义如下

            1
           / \
          2   3
         / \  /\
        4   5 6 7
       /\    /  /\
      8  9  10 11 12
     / \           \
    13 14          15
    
    然后,如上所述的访问功能将按以下顺序访问节点

    1
     2
      4
       8
        13
        14
       9
      5
     3
      6
       10
      7
       11
       12
         15
    
    现在,如果您将内存中的节点排序为15个分配的连续块,并按照上面演示的顺序存储节点,那么您通常将访问具有“”的节点。这可以根据节点结构的大小提高缓存命中率,从而加快运行速度

    创建一种快速迭代的方法,只访问树中的所有节点一次,不递归

    unsigned int g_StackDepth = 0;
    BaseNodePtr* g_Stack[MAX_STACK_DEPTH];
    
    void processTree (BaseNodePtr root, unsigned int & cnt )
    {
        g_Stack[g_StackDepth++] = root;
        while( g_StackDepth > 0 )
        {
            BaseNodePtr curr = g_Stack[--g_StackDepth];
            cnt++;
    
            if ( curr->HasNext() )
            {
                g_Stack[g_StackDepth++] = curr->Next();
            }
    
    
            if ( curr->HasChild() )
            {
                g_Stack[g_StackDepth++] = curr->Child();
            }
    
        }
    }
    
    据我所知,结合上述订购,您应该可以获得最佳速度

    显然,这是有局限性的,因为您必须知道堆栈可以提前增长多大。尽管您可以通过使用std::vector来解决这个问题。但是,使用std::vector会