为什么性能会下降?

7

我需要减少我的本地Windows C++应用程序使用的内存,同时不影响其性能。

我的主要数据结构由数千个实例组成,动态分配,以下是Line类:

struct Properties
{
    // sizeof(Properties) == 28
};


// Version 1
class Line
{
    virtual void parse(xml_node* node, const Data& data)
    {
        parse_internal(node, data);
        create();
    }

    virtual void parse_internal(xml_node*, const Data&);
    void create();

    Properties p;
};

但是我注意到我可以摆脱类成员p,因为我只需要在解析方法内部使用它,所以我改变了Line实现:

// Version 2
class Line
{
    virtual void parse(xml_node* node, const Data& data)
    {
        Properties p;

        parse_internal(node, data, &p);
        create(&p);
    }

    virtual void parse_internal(xml_node*, const Data&, Properties*);
    void create(Properties*);
};

这样可以减少分配的内存数兆,但它增加了超过50毫秒的运行时间。我想知道这是如何可能的,考虑到该应用程序已经针对发布版本进行了编译,并且开启了完全优化速度。是由于参数传递吗?还是由于我struct Properties的堆栈分配?更新:每个实例只调用一次Line::parse方法。数据结构由一个std::vector和多个线程管理的不同子集的Line组成。

2
高性能或低资源(内存)使用,只能选择其一。这是通常的情况。你往往不能同时得到两者。 - Some programmer dude
1
值得更新您的问题,以包括“parse”仅在每个“Line”实例中调用一次的明显事实。如果不是这种情况,那么这些信息甚至更加相关。 - WhozCraig
1
@Nick,感谢您澄清“parse”调用者的行为。 - WhozCraig
1
我认为你所做的是正确的,我不知道为什么会变得更慢。我可能会通过const&传递Properties而不是指针,但这不会使其运行更快。你能提供一个最小程序以重现这种行为(这样我们就可以看到如何调用/实例化它)吗? - Galik
1
我猜如果不直接看汇编代码,就很难看出是什么让它变慢。您是一次性分配所有行还是逐个分配?(也许构建“属性”时仍在i-cache中,同时您构建行,在“解析”时它不再存在,因此您必须再次获取该代码) - Hayt
显示剩余21条评论
1个回答

0

你写道parse_internal是递归的。这意味着在改变的变体中它会得到3个参数,而不是原始版本中的2个,并且会被递归调用几次。

你还必须使用指针语法来访问成员,而不是元素解引用(并可能验证Properties指针是否非空)。为了消除指针问题,你可以使用一个引用参数来调用parse_internal。

有没有理由将parse_internal作为虚成员函数,或者你可以将其更改为静态(在修改后的变体中)?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接