C ++性能/内存优化指南

时间:2010-03-31 18:19:26

标签: c++ performance optimization compiler-construction

有没有人有C ++内存优化指南的资源?最佳实践,调整等?

举个例子:

Class xxx {

    public: 
        xxx();
        virtual ~xxx();

    protected:

    private:

};

编译器或内存分配是否有任何好处可以摆脱受保护和私有,因为在这个类中没有受保护和私有的项目?

更新:程序员做了什么:

Class xxx {

    public: 
        xxx();
        virtual ~xxx();

    public:
        more stuff();
        more();

   ifndef __BUILD_WIN__
      public:
        even more();
        envenmore2();
   endif
    protected:

    private:

};

8 个答案:

答案 0 :(得分:13)

  

有没有人有C ++内存优化指南的资源?最佳实践,调整等?

这在很大程度上取决于您的编译器和目标环境(RISC,Unix / Linux,Windows)。大多数编译器都会有这样的信息。

有一些实用程序可以跟踪内存泄漏,以便您可以在测试期间修复它们。如果要动态分配很多东西(通常是C / C ++的情况),请尝试确保在销毁对象之前解除所有内容。要做到这一点:

  • 如果您重视处理器上的内存,请使用smart pointers
  • 如果你的类有任何指针的成员变量,请确保你的析构函数释放每个成员变量。将您的成员变量组合在源代码上,以便可以轻松地将这些变量与析构函数进行比较。
  • 尽可能避免动态内存分配以避免泄漏。首选std::string优先于动态分配的char*
  

是否会有任何好处   获取编译器或内存分配   从那以后摆脱受保护和私密   那里没有物品   在这堂课中保护和私人?

不,如果我没有弄错,只在编译期间检查protected / private,因此即使关键字下面有项目,它们也不会影响性能。

此外,重要的是要理解编译器是非常智能的(通常比程序员更多)因此它会优化掉任何可能的东西;例如,让我们在构造函数中声明一个变量int a。让我们说你根本不使用它,你只是忘了那里。大多数编译器甚至不会将堆栈空间保存到这些变量中。其他人需要用户激活优化才能发生这种情况,但根据经验,任何程序的生产版本都应该在启用优化的情况下编译,即使没有完整。

关于更新,您所看到的是预处理器指令,并用于执行所谓的选择性编译。看看here

答案 1 :(得分:2)

编译器不必解析它们,因此对编译器有好处。这是值得的(不是很多)。

应该没有内存使用差异。

除此之外,我能想到的唯一好处是,对于阅读代码必须处理的人来说,没有那么重要(并不是说你的例子特别麻烦)。

答案 2 :(得分:2)

Dov Bulka和David Mayhew的“Efficient C++: Performance Programming Techniques”。我不认为它是开创性的,但它肯定是一个有趣的阅读,教一些基础知识。

答案 3 :(得分:1)

公共关键字,受保护关键字和私有关键字,根本不会将其变为对象文件,因此根本没有任何好处。

一般

  • 尽量避免分配和释放内存,尽可能重用。走在堆里特别慢。
  • 完成后可用内存。除非有强烈的性能原因,否则不要闲逛。

与Java不同,当用C ++编程时,你总是需要考虑内存管理以避免泄漏。因此优化比说Java更自然。

答案 4 :(得分:0)

就一般指南而言,有What Every Programmer Should Know About Memory,但我不确定这是你想要的。

优化结构或类内存的一般指导原则是将数据成员从最大到最小排序。这可以防止多余的填充浪费在结构或类中浪费空间。

关于你的问题,我认为它已得到适当的回答,但你可以使用sizeof()来比较自己。

答案 5 :(得分:0)

  

编译器或内存分配是否有任何好处可以摆脱受保护和私有,因为在这个类中没有受保护和私有的项目?

没有。 AFAIK,非虚方法不会增加类实例的大小。

  

有没有人有C ++内存优化指南的资源?

1)如果您担心性能,请使用分析器(例如AQtime)。不要猜,使用工具。
2)一般情况下,经常(每秒几个 _millions _ 次)分配和释放内存(使用new / delete),特别是大块,这不是一个好主意。根据我的经验,这样的使用会导致性能下降。如果您经常需要使用相同的例程(使用new或std :: vector)分配大块内存,请考虑在下一次调用中重用相同的块(这在多线程应用程序中会很棘手)。即而不是

void doStuff(int memSize){
    std::vector<char> buf(memSize);
    //..some code here
}

使用类似的东西:

void doStuff(int memSize){
    static std::vector<char> buf;
    if (buf.size() < memSize)
        buf.resize(memSize);
    //..some code here
}

但仅在必要时,并且只有在您完全确定无法同时从多个单独的线程调用此例程时。 (为了使它与多线程兼容,你需要一些技巧 - 无论是互斥,还是几个缓冲区的“池”) 3)在堆栈上分配超过1兆字节(对于Windows)或8兆字节(对于Linux)将导致程序崩溃(堆栈溢出为win,在linux上为segfault),除非您在编译期间指定了堆栈大小。例如:

void doStuff(){
    char buf[1024*1024*12];//use new[] or std::vector instead of this.
    //some code here
}

这就是我能想到的全部。

答案 6 :(得分:0)

这实际上取决于您的申请。如果您正在进行模拟或任何类型的科学计算,您在大型内存阵列上进行浮点计算,那么您可以做很多事情。

  • 优化缓存重用(缓存阻塞,填充等)
  • 优化以最小化TLB命中(页面错误)
  • 将数据排列为数组结构,而不是结构数组
  • 避免不必要的内存清除
  • 避免重新分配内存,重新使用

如果您需要有许多小物件,请查看flyweight设计模式或对象池等内容。

至于担心privateprotected声明,请不要这样做。它们仅与编译相关,以强制执行封装和数据隐藏,并且不会影响生成的二进制文件。

答案 7 :(得分:0)

优化技巧 在C中优化代码有三种技术:

计算限制技术 记忆限制技术 输入/输出绑定技术

计算限制技术涉及计算执行运算符和函数所花费的时间。计算限制技术包括:

剖析 内联 循环展开 循环干扰 循环不变量计算 循环反转 尾递归消除 表查找

在内存绑定计算中,您需要考虑程序使用的内存。从存储器层次结构的较低部分使用存储器会增加执行时间。在运行程序时,您需要使用适当级别的内存。记忆限制技术包括:

参考地点 行主要寻址 填充减少 内存泄漏

在输入/输出(I / O)绑定优化中,顺序访问和随机访问方法用于减少检索信息所需的时间。

缓冲I / O比无缓冲I / O快。您可以对大缓冲区使用read()和write()函数。您可以使用mmap()来减少检索信息所需的时间。 Mmap()使用共享内存或文件映射进程的地址空间。

更多优化技术是:

尽量减少程序中全局变量的使用。

将全局变量以外的所有函数声明为文件中的静态。

使用字大小变量,例如int和float,而不是char,short和double。

避免使用递归。

避免使用sqrt()函数,因为它是CPU密集型的。

使用一维数组。

请勿将密切相关的功能拆分为单独的文件。

使用puts()函数代替printf函数。

使用未格式化/二进制文件访问而不是格式化文件访问。

如果编译器支持此函数来控制malloc函数,请使用mallopt()。

使用宏而不是小函数来节省CPU时间。