循环调用的函数,将函数变量声明提升到全局以缓存,是否能提高性能? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
luoway
V2EX    程序员

循环调用的函数,将函数变量声明提升到全局以缓存,是否能提高性能?

  •  
  •   luoway 2015-10-07 00:00:32 +08:00 3794 次点击
    这是一个创建于 3661 天前的主题,其中的信息可能已经有所发展或是发生改变。
    既然是变量,肯定是要赋值的,那么“声明+赋值”,与仅有“赋值”,性能有没有差距呢?

    有没有语言是声明一次,指定一块内存空间,而减少声明可以减少这点性能消耗?

    感觉有些杞人忧天了……
    15 条回复    2015-10-08 15:10:23 +08:00
    lzhtony
        1
    lzhtony  
       2015-10-07 00:13:44 +08:00
    同一个变量多次声明(比如循环中)编译器一般会优化,不同的变量肯定是不行了.
    squid157
        2
    squid157  
       2015-10-07 00:17:26 +08:00
    解释器那样的估计会有小提升。但这个算不算 premature optimization ,我就不知道了。还是写完了跑 profile 吧。
    zonyitoo
        3
    zonyitoo  
       2015-10-07 00:26:40 +08:00
    无论如何,你的那个「变量」肯定是要重新给初始值的吧,那么这一次的初始化无可避免。
    函数调用时的局部变量就放在栈上,通过 esp, ebp 来找到相对应的栈内存空间,不觉得这里面会有什么可以优化的地方。
    而且,编译器可能会把一些临时变量放到寄存器上的,你放在全局那就肯定不能做这个优化了吧。
    msg7086
        4
    msg7086  
       2015-10-07 04:07:12 +08:00
    通常编译器会帮你优化掉。
    Andiry
        5
    Andiry  
       2015-10-07 04:32:48 +08:00
    提升到全局以缓存是什么鬼,难道放在栈里就不会缓存了吗?
    ryd994
        6
    ryd994  
       2015-10-07 07:11:26 +08:00 via Android
    别,编译器优化比人强
    iyangyuan
        7
    iyangyuan  
       
    这种优化带来的效率提升可以忽略不计,一般是优化算法或者架构
    firebroo
        8
    firebroo  
       2015-10-07 11:14:52 +08:00 via Android
    声明,定义, lz 的“声明”应该是定义,“赋值”应该是初始化。 c 语言的 extern 声明是给编译器看的。
    yuchting
        9
    yuchting  
       2015-10-07 11:54:46 +08:00
    我曾经试图想超过编译器优化,从 java 到 c/c++,最后在 c 混合编程 asm 中的一句 sincos cpu 浮点运算器的指令中战胜了 c 本身调用 sin 、 cos 函数加起来的时间。

    从此,我再也不想什么语法优化了,在算法上下功夫优化才是正道……
    luoway
        10
    luoway  
    OP
       2015-10-07 12:48:03 +08:00
    @yuchting 这个例子明明是说语法优化不如直接用汇编语言……

    按问题描述,我想到的是这样提升到全局,会污染全局变量的命名空间,而对性能的改善不明显。
    现在参考大家的想法看来,对性能的改善都没有,的确是个馊主意了
    semicircle21
        11
    semicircle21  
       2015-10-07 20:27:35 +08:00
    对性能的优化微乎其微, 而且这样你的函数就不可重入的了..
    更详细的分析要看代码。
    akira
        12
    akira  
       2015-10-07 22:57:03 +08:00
    对于大部分编译型语言来说,很有可能不但没有性能上的改善,反而会导致性能下降。
    qwsqwa
        13
    qwsqwa  
       2015-10-08 13:44:49 +08:00
    C/C++中有静态局部变量, static 关键字。静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。
    qwsqwa
        14
    qwsqwa  
       2015-10-08 13:45:35 +08:00
    java 和 C#中好像也有,其他语言就不清楚了。
    VYSE
        15
    VYSE  
       2015-10-08 15:10:23 +08:00
    以 C 、 X86 为例,不论你多少层循环,所有使用的局部变量都在进入函数前预先确定在当前 stack frame 的偏移,而栈在程序启动时候就预先分配好固定尺寸了,之后仅仅是算个内存地址存哪而已,除非放在堆上动态 malloc 。
    也就说本来就是栈上的一个复用内存,跟全局变量一个概念(好吧全局变量就是放在低的栈上)。
    而且全局会变慢, CPU CACHE 一段运行时连续的内存区域,因此在一个函数里操作自己栈上东西都可以在 CPU 内部完成,而 refer 一个远处的全局内存, CPU 不得不去到低速的内存上去访问数据。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3078 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 00:28 PVG 08:28 LAX 17:28 JFK 20:28
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86