- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
不确定之前是否有人问过这个问题。在回答 this very simple question 时,我问自己以下内容。考虑一下:
void foo()
{
int i{};
const ReallyAnyType[] data = { item1, item2, item3,
/* many items that may be potentially heavy to recreate, e.g. of class type */ };
/* function code here... */
}
现在理论上,每次控制达到功能时都会重新创建局部变量,对吗? IE。看看上面的 int i
- 它肯定会在堆栈上重新创建。上面的数组呢?编译器能否聪明到优化它的创建只发生一次,还是我在这里需要一个 static
修饰符?如果数组不是 const
怎么办? (好吧,如果它不是 const
,我可能只创建它一次就没有意义,因为由于在函数执行期间进行修改,调用之间可能需要重新初始化到默认状态。)
这听起来像是一个基本问题,但出于某种原因我仍在思考。另外,忽略“你为什么要这样做”——这只是一个语言问题,不适用于某个编程问题或设计。我在这里指的是 C 和 C++。如果两者在这个问题上有分歧,请概述。
最佳答案
我认为这里有两个问题:
编译器可以优化非static
const
对象使其有效地static
以便它只创建一次;和
给定的编译器会这样做是否合理。
我认为第二个问题的答案是“否”,因为我不明白进行大量控制流分析以节省程序员输入单词 static
的麻烦的意义>。然而,我经常对人们花时间编写的优化感到惊讶(而不是我认为他们应该致力于的优化:-))。尽管如此,如果您需要的话,我强烈建议您使用 static
这个词。
对于第一个问题,在某些情况下编译器可以根据“as-if”规则进行优化,但在极少数情况下会成功。
首先,如果初始化器中的任何对象或子对象具有非平凡的构造函数/析构函数,那么构造/析构是可见的,这不是复制省略的例子。 (当然,本段仅适用于 C++。)
如果初始化列表中的任何计算具有可见的副作用,情况也是如此。
不言而喻,如果任何子对象的值不是常量,则需要在每次构造时对该子对象进行计算。
如果对象和所有子对象都是普通可复制的,所有初始化列表计算都是常量,唯一的构造成本是从模板复制到对象,那么编译器仍然无法执行优化如果有对象的多个事件实例的地址有可能同时可见。例如,如果函数是递归的,并且在某处使用了对象的地址(对于数组来说很难避免),那么可能会比较来自函数的不同递归调用的其中两个对象的地址。而且它们必须比较不相等,因为它们实际上是不同的对象。 (而且,现在我想到了,该函数甚至不需要在多线程环境中递归。)
因此,对于希望将该对象优化为单个静态实例的编译器来说,举证责任非常高。正如我所说,给定的编译器很可能实际上尝试执行该任务,但我绝对不希望它这样做。
关于c++ - 将函数内的大变量声明为 `static` 在性能上有什么不同吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35249932/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!