当前位置: 首页 > article >正文

05 HarmonyOS NEXT高效编程秘籍:Arkts函数调用与声明优化深度解析

温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦!

目录

    • 概述
    • 函数调用优化
      • 声明参数要和实际的参数一致
        • 反例
        • 正例
      • 函数内部变量尽量使用参数传递
        • 反例
        • 正例
    • 函数与类声明优化
      • 避免动态声明function与class
        • 反例
        • 正例
    • 性能测试示例
    • 性能测试结果分析
    • 最佳实践建议

概述

本篇文章,将焦点转向函数调用与函数声明的优化策略。在HarmonyOS NEXT API12+的开发过程中,函数的精准定义与高效调用是提升应用性能的关键所在。本文将通过一个具体计算器应用的实例,逐一揭晓几种经过实践检验的优化技巧,旨在引导开发者如何编写出更加高效的代码,从而优化应用性能和用户体验。

函数调用优化

声明参数要和实际的参数一致

在HarmonyOS NEXT开发中,声明的参数要和实际的传入参数个数及类型一致,否则会导致运行时走入慢速路径,影响性能。

反例
 
@Entry
@Component
struct CalculatorBad {
  @State result: string = '0';

  // 参数声明与实际使用不一致的计算函数
  calculate(operation: string, a: number, b: number) {
    switch(operation) {
      case 'add':
        // 错误:传入了多余的参数
        return this.add(a, b, 0);
      case 'subtract':
        // 错误:参数类型不匹配
        return this.subtract(a.toString(), b.toString());
      default:
        return 0;
    }
  }

  // 基础数学运算函数
  add(a: number, b: number) {
    return a + b;
  }

  subtract(a: number, b: number) {
    return a - b;
  }

  build() {
    Column() {
      Text(this.result)
        .fontSize(30)
        .margin(20)
      
      Row() {
        Button('计算示例')
          .onClick(() => {
            // 错误调用方式
            this.result = this.calculate('add', 1, 2, 3).toString();
          })
      }
    }
    .width('100%')
    .height('100%')
  }
}
正例
 
@Entry
@Component
struct CalculatorGood {
  @State result: string = '0';
  @State num1: string = '';
  @State num2: string = '';

  // 使用接口定义计算器操作
  interface Operation {
    calculate(a: number, b: number): number;
    symbol: string;
  }

  // 预定义所有操作类型
  private operations: Record<string, Operation> = {
    add: {
      calculate: (a: number, b: number): number => a + b,
      symbol: '+'
    },
    subtract: {
      calculate: (a: number, b: number): number => a - b,
      symbol: '-'
    }
  };

  // 参数类型和数量完全匹配的计算函数
  calculate(operation: string): void {
    const op = this.operations[operation];
    if (!op) return;

    const a = Number(this.num1);
    const b = Number(this.num2);
    
    // 参数类型和数量完全匹配
    this.result = op.calculate(a, b).toString();
  }

  build() {
    Column() {
      // 计算结果显示
      Text(this.result)
        .fontSize(30)
        .margin(20)
      
      // 输入框
      TextInput({ placeholder: '第一个数字' })
        .width('80%')
        .margin(10)
        .onChange((value: string) => {
          this.num1 = value;
        })
      
      TextInput({ placeholder: '第二个数字' })
        .width('80%')
        .margin(10)
        .onChange((value: string) => {
          this.num2 = value;
        })
      
      // 操作按钮
      Row() {
        ForEach(Object.keys(this.operations), (key: string) => {
          Button(this.operations[key].symbol)
            .margin(10)
            .onClick(() => {
              // 正确的参数传递方式
              this.calculate(key);
            })
        })
      }
      .margin(20)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

函数内部变量尽量使用参数传递

在HarmonyOS NEXT开发中,能传递参数的尽量传递参数,不要使用闭包。闭包作为参数会多一次闭包创建和访问,影响性能。

反例
 
@Component
struct CalculationHistoryBad {
  // 全局历史记录
  private static history: string[] = [];

  // 错误示例:使用闭包访问外部变量
  addToHistory() {
    // 通过闭包访问静态变量,性能较差
    CalculationHistoryBad.history.push(`计算时间: ${new Date().toLocaleString()}`);
  }

  clearHistory() {
    // 通过闭包访问静态变量,性能较差
    CalculationHistoryBad.history = [];
  }

  build() {
    Column() {
      // 通过闭包访问历史记录
      ForEach(CalculationHistoryBad.history, (item: string) => {
        Text(item)
          .fontSize(16)
          .margin(5)
      })
    }
  }
}
正例
 
@Component
struct CalculationHistoryGood {
  @State history: string[] = [];

  // 正确示例:通过参数传递数据
  addToHistory(record: string): void {
    // 通过参数传递,性能更好
    this.history = [...this.history, record];
  }

  // 使用参数传递新的历史记录状态
  updateHistory(newHistory: string[]): void {
    this.history = newHistory;
  }

  build() {
    Column() {
      // 直接使用组件状态
      ForEach(this.history, (item: string) => {
        Text(item)
          .fontSize(16)
          .margin(5)
      })

      Button('添加记录')
        .onClick(() => {
          // 通过参数传递数据
          this.addToHistory(`计算时间: ${new Date().toLocaleString()}`);
        })

      Button('清空记录')
        .onClick(() => {
          // 通过参数传递空数组
          this.updateHistory([]);
        })
    }
  }
}

函数与类声明优化

避免动态声明function与class

在HarmonyOS NEXT开发中,动态声明function和class会导致每次调用都重新创建,对内存和性能都会有影响。

反例
 
@Entry
@Component
struct CalculatorFactoryBad {
  @State result: string = '0';

  // 错误示例:动态创建计算器类
  createCalculator(type: string) {
    if (type === 'scientific') {
      // 每次调用都会创建新的类,性能差
      return class ScientificCalculator {
        sin(x: number): number {
          return Math.sin(x);
        }
        cos(x: number): number {
          return Math.cos(x);
        }
      }
    } else {
      // 每次调用都会创建新的类,性能差
      return class BasicCalculator {
        add(a: number, b: number): number {
          return a + b;
        }
        subtract(a: number, b: number): number {
          return a - b;
        }
      }
    }
  }

  build() {
    Column() {
      Text(this.result)
        .fontSize(30)
      Button('创建计算器')
        .onClick(() => {
          // 每次点击都会创建新的类实例
          const Calculator = this.createCalculator('scientific');
          const calc = new Calculator();
          this.result = calc.sin(30).toString();
        })
    }
  }
}
正例
 
// 预定义计算器接口
interface ICalculator {
  calculate(x: number, y?: number): number;
  getType(): string;
}

// 预定义所有计算器类
class ScientificCalculator implements ICalculator {
  private static instance: ScientificCalculator;

  // 使用单例模式
  static getInstance(): ScientificCalculator {
    if (!ScientificCalculator.instance) {
      ScientificCalculator.instance = new ScientificCalculator();
    }
    return ScientificCalculator.instance;
  }

  calculate(x: number): number {
    return Math.sin(x);
  }

  getType(): string {
    return '科学计算器';
  }
}

class BasicCalculator implements ICalculator {
  private static instance: BasicCalculator;

  static getInstance(): BasicCalculator {
    if (!BasicCalculator.instance) {
      BasicCalculator.instance = new BasicCalculator();
    }
    return BasicCalculator.instance;
  }

  calculate(x: number, y: number): number {
    return x + y;
  }

  getType(): string {
    return '基础计算器';
  }
}

@Entry
@Component
struct CalculatorFactoryGood {
  @State result: string = '0';
  @State currentType: string = 'basic';

  // 工厂函数返回预定义的类实例
  getCalculator(type: string): ICalculator {
    switch (type) {
      case 'scientific':
        return ScientificCalculator.getInstance();
      default:
        return BasicCalculator.getInstance();
    }
  }

  build() {
    Column() {
      Text(this.result)
        .fontSize(30)
        .margin(20)

      Text(`当前模式: ${this.getCalculator(this.currentType).getType()}`)
        .fontSize(20)
        .margin(10)

      Row() {
        Button('基础模式')
          .margin(10)
          .onClick(() => {
            this.currentType = 'basic';
            const calc = this.getCalculator('basic');
            this.result = calc.calculate(1, 2).toString();
          })

        Button('科学模式')
          .margin(10)
          .onClick(() => {
            this.currentType = 'scientific';
            const calc = this.getCalculator('scientific');
            this.result = calc.calculate(30).toString();
          })
      }
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

性能测试示例

下面是一个简单的性能测试组件,用于比较不同实现方式的性能差异:

  // performance-test.ets

@Component
export struct PerformanceTest {
    @State testResults: string = '';

    aboutToAppear() {
        this.runPerformanceTests();
    }

    // 性能测试函数
    async runPerformanceTests() {
        const iterations = 100000;
        const testArray = [1, 2, 3, 4, 5];

        // 测试1: 使用闭包
        const startTime1 = new Date().getTime();
        let sum1 = 0;

        const sumWithClosure = () => {
            for (let i = 0; i < testArray.length; i++) {
                sum1 += testArray[i];
            }
            return sum1;
        }

        for (let i = 0; i < iterations; i++) {
            sumWithClosure();
        }
        const endTime1 = new Date().getTime();

        // 测试2: 使用参数传递
        const startTime2 = new Date().getTime();
        let sum2 = 0;

        const sumWithParams = (arr: number[]): number => {
            let localSum = 0;
            for (let i = 0; i < arr.length; i++) {
                localSum += arr[i];
            }
            return localSum;
        }

        for (let i = 0; i < iterations; i++) {
            sum2 = sumWithParams(testArray);
        }
        const endTime2 = new Date().getTime();

        // 更新测试结果
        this.testResults = `
闭包方式耗时: ${endTime1 - startTime1}ms
参数传递耗时: ${endTime2 - startTime2}ms

闭包结果: ${sum1}
参数传递结果: ${sum2}
    `;
    }

    build() {
        Column() {
            Text('性能测试结果')
                .fontSize(24)
                .margin(20)

            Text(this.testResults)
                .fontSize(16)
                .margin(20)

            // 添加更多测试用例
            Button('运行更多测试')
                .onClick(() => {
                    this.runMoreTests();
                })
                .margin(20)
        }
        .width('100%')
            .height('100%')
            .justifyContent(FlexAlign.Center)
    }

    // 更多性能测试用例
    async runMoreTests() {
        const iterations = 100000;
        const testArray = [1, 2, 3, 4, 5];

        // 测试3: 动态函数声明
        const startTime3 = new Date().getTime();
        let sum3 = 0;

        for (let i = 0; i < iterations; i++) {
            const dynamicSum =  (arr: number[]): number=> {
                let localSum = 0;
                for (let j = 0; j < arr.length; j++) {
                    localSum += arr[j];
                }
                return localSum;
            };
            sum3 = dynamicSum(testArray);
        }
        const endTime3 = new Date().getTime();

        // 测试4: 预定义函数
        const startTime4 = new Date().getTime();
        let sum4 = 0;

        const predefinedSum = (arr: number[]): number => {
            let localSum = 0;
            for (let i = 0; i < arr.length; i++) {
                localSum += arr[i];
            }
            return localSum;
        };

        for (let i = 0; i < iterations; i++) {
            sum4 = predefinedSum(testArray);
        }
        const endTime4 = new Date().getTime();

        // 更新测试结果
        this.testResults += `

动态函数声明耗时: ${endTime3 - startTime3}ms
预定义函数耗时: ${endTime4 - startTime4}ms

动态函数结果: ${sum3}
预定义函数结果: ${sum4}
    `;
    }
}

性能测试结果分析

通过上述性能测试组件,我们可以得出以下结论:

  1. 参数传递 vs 闭包:使用参数传递的方式比使用闭包访问外部变量的性能更好,因为闭包需要额外的创建和访问成本。

  2. 预定义函数 vs 动态函数:预定义函数的性能明显优于动态声明的函数,因为动态声明会在每次调用时重新创建函数对象。

  3. 内存使用:使用参数传递和预定义函数的方式不仅执行速度更快,而且内存使用也更加高效,因为避免了额外的闭包对象和动态函数对象的创建。

最佳实践建议

基于上述性能测试结果,我们建议在HarmonyOS NEXT开发中遵循以下最佳实践:

  1. 函数参数传递

    • 优先使用参数传递而不是闭包访问外部变量
    • 确保参数类型和数量的一致性
    • 避免使用可选参数,而是使用明确的函数重载
  2. 函数声明方式

    • 使用预定义的函数而不是动态声明
    • 采用单例模式管理类实例
    • 避免在循环或条件语句中声明函数
  3. 性能优化技巧

    • 使用TypeScript的类型系统确保类型安全
    • 避免不必要的对象创建和内存分配
    • 利用接口和类型定义提高代码的可维护性

通过遵循这些最佳实践,我们可以编写出更高效、更可靠的HarmonyOS NEXT应用程序。


http://www.kler.cn/a/571900.html

相关文章:

  • 复合机器人为 CNC 毛坯件上下料注入 “智能强心针”
  • CentOS 7中安装Dify
  • Docker 容器的数据卷
  • LeetCode 42.接雨水
  • 虚拟机IP的配置,让它上网
  • 奖学金(acwing)c++
  • Redis 排行榜实现:处理同分数时的排名问题
  • 探秘基带算法:从原理到5G时代的通信变革【八】QAM 调制 / 解调
  • SSH远程登录并执行命令
  • 【Office-Word】如何自动生成中英文目录
  • 【ATXServer2】Android无法正确显示手机屏幕
  • Android如何将原生的anr,tombstones,dropbox 换分区存储位置
  • 健康养生,开启活力生活
  • Linux驱动开发-字符设备驱动开发
  • 微服务架构中处理用户认证信息的5种方案
  • 数据显示不符合用户阅读习惯
  • Virtual Box虚拟机安装Mac苹果Monterey和big sur版本实践
  • 解决跨域请求的问题(CORS)
  • # 【Unity】【游戏开发】赛车游戏中碰撞加速的实现方法
  • Ubuntu20.04双系统安装及软件安装(四):国内版火狐浏览器