我有一个广泛使用STL向量和Boost多阵列的应用程序。该应用程序对性能非常敏感,因为它实时分析大量数据。
由于向量和多个数组进行了越界检查,因此我预计会因此而导致一些性能损失。我想知道是否有一种方法只允许在开发期间进行错误检查,但在生产中禁用它。
所以,我想知道这是否确实可行,以及它是否会对我的容器的性能产生影响?
答案 0 :(得分:2)
在实践中,我所看到的所有STL实现(VC,GCC等)完全符合您的要求。他们可能在调试/开发版本中有一些边界检查,但是当你构建版本时,它们都会省略它们。对于Boost容器也是如此(AFAIK)(例如see here,如另一个答案所述。)
在某些情况下,不同的访问方法在边界检查方面具有不同的行为。例如,std::vector
成员函数at()
总是执行边界检查,但索引操作符([]
)在release / nondebug构建中不会这样做。
最后,如果这对您很重要,您应该只看一下您正在使用的实现并确保。它只是几个容器上的一些功能。
关于边界检查的性能成本。在实践中,所有提供的STL算法都将使用未经检查的访问容器(他们在前面进行错误检查,从那时起就不会打扰。)因此,如果使用STL算法,你不会看到任何性能开销。
在您自己的代码中,在紧密的内部循环中,您可能会看到绑定检查对性能的负面影响。我还没有完成任何基准测试,但我认为在大多数情况下它会很小并且可以忽略不计。此外,在绝大多数用例中,您可以使用STL算法(for_each
,accumulate
,count_if
等)替换手写循环,这将消除最低成本
答案 1 :(得分:2)
在提升中,您的问题的答案如下: http://lists.boost.org/boost-users/2006/02/16960.php
简而言之,范围检查基于boost/assert.hpp
:可以通过定义BOOST_DISABLE_ASSERTS
或NDEBUG
来禁用它们(您可以将其中一个作为编译器选项传递)。 / p>
在std向量中,at()
确实检查了边界,但[]
没有。在大多数常见的编译器实现中,可以启用边界检查,但这必须显式完成(通常通过传递特殊标志或启用调试模式)。因此,您的[]
操作已针对向量进行了优化。