为什么会出现这种性能下降?

Why this performance deterioration?

提问人:Nick 提问时间:10/21/2016 最后编辑:Nick 更新时间:10/21/2016 访问量:187

问:

我需要减少本机 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;
};

但是由于我注意到我可以摆脱类成员,因为我只需要在parse方法中使用它,因此我更改了实现:pLine

// 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

更新:

该方法仅对每个实例调用一次。数据结构由 s 的 a 组成。多个线程管理此向量的不同子集。Line::parsestd::vectorLine

C++ 性能 内存管理 参数传递

评论

2赞 Some programmer dude 10/21/2016
高性能或低资源(内存)使用率,选择一个。这是通常的交易。你往往不能两者兼得。
1赞 WhozCraig 10/21/2016
值得更新您的问题,以包括每个实例仅调用一次的明显事实。如果不是这样,那么这些信息就有意义了。parseLine
1赞 WhozCraig 10/21/2016
@Nick感谢您澄清 的来电者行为。parse
1赞 Galik 10/21/2016
我认为你所做的是正确的,我不知道为什么这会更慢。我可能会传递指针而不是指针,但这不会使它运行得更快。你能提供一个最小的程序来重现这种行为吗(这样我们就可以真正看到它是如何被调用/实例化的)?Propertiesconst&
1赞 Hayt 10/21/2016
我想如果不实际查看组件,就很难看出是什么让它变慢。您是同时分配所有线路还是随着时间的推移分配所有线路?(也许当你构造行时,它的“构造”仍然在 i-cache 中,而它不再是了,所以你必须再次获取该代码)Propertiesparse

答:

0赞 Hans Olsson 10/21/2016 #1

你写parse_internal是递归的。这意味着它在更改后的变体中获得 3 个参数,而不是原始变体中的 2 个参数 - 并且递归调用几次。

您还必须使用指针语法而不是元素取消引用来访问成员(并可能验证 Properties 指针是否为非 null)。若要消除指针问题,可以使用引用参数来parse_internal。

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