暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

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

原创 若城 2025-03-04
1087

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

目录

概述

本篇文章,将焦点转向函数调用与函数声明的优化策略。在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应用程序。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论