当前位置:  开发笔记 > 编程语言 > 正文

C++异常处理添加了多少占用空间

如何解决《C++异常处理添加了多少占用空间》经验,为你挑选了3个好方法。

这个问题对于嵌入式开发尤为重要.异常处理为生成的二进制输出增加了一些空间.另一方面,没有例外,错误需要以其他方式处理,这需要额外的代码,这最终也会增加二进制大小.

我对你的经历很感兴趣,特别是:

    编译器为异常处理添加的平均占用空间是多少(如果有这样的测量)?

    在二进制输出大小方面,异常处理是否真的比其他错误处理策略更昂贵(很多人说)?

    你会为嵌入式开发建议什么样的错误处理策略?

请仅以我的问题为指导.欢迎任何输入.

附录:对于特定的C++对象/可执行文件,是否有任何人具有具体的方法/脚本/工具,它将显示由编译器生成的代码和专用于异常处理的数据结构占用的已加载内存占用的百分比?



1> bias..:

发生异常,会产生时间开销,具体取决于您实现异常处理的方式.但是,作为轶事,应该导致异常的事件的严重性将花费同样多的时间来处理使用任何其他方法.为什么不使用高度支持的基于语言的方法来处理这些问题呢?

GNU C++编译器默认使用零成本模型,即在不发生异常时没有时间开销.

由于有关异常处理代码和本地对象偏移的信息可以在编译时计算一次,因此这些信息可以保存在与每个函数关联的单个位置,但不能保存在每个ARI中.您基本上可以从每个ARI中删除异常开销,从而避免将额外时间推送到堆栈上.这种方法称为异常处理的零成本模型,前面提到的优化存储称为影子堆栈. - Bruce Eckel,思考C++第2卷

规模复杂性开销不容易量化,但Eckel平均表示5%和15%.这取决于异常处理代码的大小与应用程序代码大小的比率.如果你的程序很小,那么异常将是二进制文件的很大一部分.如果您使用零成本模型而不是异常会占用更多空间来消除时间开销,因此如果您关心空间而不是时间而不是使用零成本编译.

我的观点是,大多数嵌入式系统都有足够的内存,如果你的系统有一个C++编译器,你有足够的空间来包含异常.我项目使用的PC/104计算机有几GB的二级存储器,512 MB的主存储器,因此没有空间问题 - 但是,我们的微控制器是用C编程的.我的启发式是"如果有一个主流的C++编译器它,使用例外,否则使用C".


[续]除非您有严格的政府要求或完全合理的内部要求,否则最好默认和安全.然后,在经验证明之后转向更复杂的设计.因此,从*nix和gcc开始,但有例外.根据需要迁移.

2> 小智..:

测量的东西,第2部分.我现在有两个程序.第一个是在C中,用gcc -O2编译:

#include 
#include 

#define BIG 1000000

int f( int n ) {
    int r = 0, i = 0;
    for ( i = 0; i < 1000; i++ ) {
        r += i;
        if ( n == BIG - 1 ) {
            return -1;
        }
    }
    return r;
}

int main() { 
    clock_t start = clock();
    int i = 0, z = 0;
    for ( i = 0; i < BIG; i++ ) {
        if ( (z = f(i)) == -1 ) { 
            break;
        }
    }
    double t  = (double)(clock() - start) / CLOCKS_PER_SEC;
    printf( "%f\n", t );
    printf( "%d\n", z );
}

第二个是C++,带有异常处理,用g ++ -O2编译:

#include 
#include 

#define BIG 1000000

int f( int n ) {
    int r = 0, i = 0;
    for ( i = 0; i < 1000; i++ ) {
        r += i;
        if ( n == BIG - 1 ) {
            throw -1;
        }
    }
    return r;
}

int main() { 
    clock_t start = clock();
    int i = 0, z = 0;
    for ( i = 0; i < BIG; i++ ) {
        try {
         z += f(i); 
        }
        catch( ... ) {
            break;
        }

    }
    double t  = (double)(clock() - start) / CLOCKS_PER_SEC;
    printf( "%f\n", t );
    printf( "%d\n", z );
}

我认为这些回答了我上一篇文章的所有批评.

结果:执行时间使C版本比C++版本具有0.5%的优势,但不是其他人已经谈过的10%(但没有演示)

我会非常感激,如果其他人可以尝试编译和运行代码才能(只需要几分钟的时间)来检查,我还没有做出可怕的和明显的错误在任何地方.这被称为"科学方法"!


exe大小差异非常大,因为这是一个非常简单的例子.可能大部分开销都是异常支持功能本身.当原始exe为1或2M时,开销可能变得不那么重要.
这个线程很旧,我只是用gcc 4.4.4重新编译代码,现在大小差异是348字节(7638字节有例外,7290没有例外)

3> Alex..:

我在低延迟环境中工作.(对于我在"生产链"中的应用而言,300微秒以下)根据我的经验,异常处理会增加5-25%的执行时间,具体取决于您的工作量!

我们一般不关心二元臃肿,但是如果你得到太多臃肿然后你就像疯了一样捶打,所以你需要小心.

只需保持二进制文件合理(取决于您的设置).

我对我的系统进行了大量的分析.
其他令人讨厌的地区:

记录

坚持(我们只是不做这个,或者如果我们这样做的话)


您是否在启用和未启用异常处理的情况下编译相同的代码并查看性能差异?你用了什么编译器?如果您正在使用GCC,我怀疑性能差异是由于空间开销导致二进制文件扩展到不适合缓存或类似的一些副作用,而不是异常处理本身.
推荐阅读
wurtjq
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有