zoukankan      html  css  js  c++  java
  • iOS 的尾调用优化原理

    背景:

    今天聊代码规范的问题的时候说了一下尾调用的问题。

    一:概念:

    什么是尾调用?

    尾调用(Tail Call):某个函数的最后一步仅仅只是调用了一个函数(可以是自身,可以是另一个函数)。

    注意 “仅仅” 两个字。

    例子:

    // 尾调用:
    - (NSInteger)funcA:(NSInteger)num {
    
        /*  Some codes... */
    
        if (num == 0) {
            return [self funcA:num];// 尾调用->自身
        }    
    
        if (num > 0) {
            return [self funcB:num];// 尾调用->函数funcB
        }    
    
        return [self funcC:num];// 尾调用->函数funcC
    }
    
    // 不是尾调用1:
    - (NSInteger)funcA:(NSInteger)num {
    
        NSInteger num = [self funcB:(num)];
    
        return num;// 不是尾调用->最后一步是返回一个值,而不是调用一个函数
    }
    
    // 不是尾调用2:
    - (NSInteger)funcA:(NSInteger)num {
    
        return [self funcB:(num)] + 1;// 不是尾调用->原因:最后一步不仅调用了函数还有 +1 操作
    }
    

    二:优化点(尾调用优化在Release模式下才会有,Debug模式下没有。)

    例子:一直开辟新的栈空间(最后会栈溢出,最终导致崩溃。空间复杂度O(n),时间复杂度O(n)。)

    例子:尾调用的优化可以重复利用栈空间(重用栈帧,不申请栈空间。
    空间复杂度O(1),时间复杂度O(n)。)

    三、总结

    总结:
    1. 尾调用:某个函数的最后一步仅仅调用了一个函数(可以是自身,可以是另一个函数)。
    2. OC的尾调用优化的本质是:栈帧的复用
    3. 尾调用优化实现原理:当函数A的最后一步仅仅是调用另一个函数B时(或者调用自身函数A),这时,因为函数A的位置信息和内部变量已经不会再用到了,直接把函数A的栈帧交给函数B使用。


    四:附加思考:
     

    思考:尾调用尾部加0可以达到尾调用优化,加.0就不能达到,是为什么呢?

    注:

    参考:https://www.jianshu.com/p/9e3cd9b1095a

  • 相关阅读:
    HDU 3757 Evacuation Plan DP
    UVa 1473
    LA 6047 Perfect Matching 字符串哈希
    HDU 3038 How Many Answers Are Wrong 并查集带权路径压缩
    专业程序员必知必会技巧:驯服复杂代码
    OpenCV、OpenCL、OpenGL、OpenPCL
    关于dlg和pro的问题
    关于编译PCL1.71
    VS2010编译错误:fatal error C1189: #error : This file requires _WIN32_WINNT to be #defined at least to 0x
    AI:从游戏引擎--到AI
  • 原文地址:https://www.cnblogs.com/miaomiaocat/p/12955829.html
Copyright © 2011-2022 走看看