写点什么

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

作者:全栈若城
  • 2025-03-04
    北京
  • 本文字数:7711 字

    阅读完需:约 25 分钟

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

@

  • 概述

  • 函数调用优化声明参数要和实际的参数一致函数内部变量尽量使用参数传递

  • 函数与类声明优化避免动态声明 function 与 class

  • 性能测试示例

  • 性能测试结果分析

  • 最佳实践建议


概述

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

函数调用优化

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

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

反例

 @Entry@Componentstruct 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@Componentstruct 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 开发中,能传递参数的尽量传递参数,不要使用闭包。闭包作为参数会多一次闭包创建和访问,影响性能。

反例

 @Componentstruct 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)      })    }  }}
复制代码

正例

 @Componentstruct 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@Componentstruct 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@Componentstruct 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
@Componentexport 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 应用程序。

发布于: 刚刚阅读数: 3
用户头像

全栈若城

关注

解读Python与前端技术,助你成为技术大牛 2023-06-28 加入

我是一名专注于 Python 和前端技术的技术讲解者。我擅长将复杂的技术概念转化为简单易懂的语言,帮助初学者快速入门,并满足高级开发者对更深入理解的需求。

评论

发布
暂无评论
05 HarmonyOS NEXT高效编程秘籍:Arkts函数调用与声明优化深度解析_HarmonyOS NEXT_全栈若城_InfoQ写作社区