一盛撑、引言
在應(yīng)用開發(fā)中植阴,高性能編程對于提升用戶體驗至關(guān)重要。本文將詳細(xì)介紹鴻蒙Next ArkTS在高性能編程方面的實(shí)踐經(jīng)驗勤家,包括聲明與表達(dá)式腹尖、函數(shù)、數(shù)組以及異常處理等方面的優(yōu)化技巧伐脖,助力開發(fā)者打造高效能的應(yīng)用热幔。
二、聲明與表達(dá)式
(一)使用const聲明不變的變量
在編程過程中讼庇,對于那些在后續(xù)代碼中不會發(fā)生改變的變量断凶,應(yīng)使用const
進(jìn)行聲明。這樣做不僅可以使代碼意圖更加清晰巫俺,還能幫助編譯器進(jìn)行優(yōu)化认烁。例如:
const index = 10000; // 該變量在后續(xù)過程中未發(fā)生改變,建議聲明成常量
(二)number類型變量避免整型和浮點(diǎn)型混用
ArkTS運(yùn)行時在優(yōu)化時會區(qū)分整型和浮點(diǎn)型數(shù)據(jù)介汹,因此建議在初始化后避免改變number
類型變量的數(shù)據(jù)類型却嗡。例如:
let intNum = 1;
intNum = 1.1; // 該變量在聲明時為整型數(shù)據(jù),建議后續(xù)不要賦值浮點(diǎn)型數(shù)據(jù)
let doubleNum = 1.1;
doubleNum = 1; // 該變量在聲明時為浮點(diǎn)型數(shù)據(jù)嘹承,建議后續(xù)不要賦值整型數(shù)據(jù)
(三)數(shù)值計算避免溢出
在進(jìn)行數(shù)值計算時窗价,要特別注意可能導(dǎo)致溢出的情況。常見的溢出場景包括加法叹卷、減法撼港、乘法、指數(shù)運(yùn)算以及&(and)
骤竹、>>>(無符號右移)
等運(yùn)算操作帝牡。溢出會導(dǎo)致引擎進(jìn)入慢速的溢出邏輯分支處理,影響性能蒙揣。因此靶溜,應(yīng)確保數(shù)值在合適的范圍內(nèi),避免大于INT32_MAX
或小于INT32_MIN
(對于某些運(yùn)算操作懒震,如&
罩息、>>>
等,應(yīng)避免大于INT32_MAX
)个扰。
(四)循環(huán)中常量提取瓷炮,減少屬性訪問次數(shù)
在循環(huán)中,如果存在大量對常量的訪問操作递宅,且這些常量在循環(huán)過程中不會改變娘香,那么可以將其提取到循環(huán)外部冬筒。這樣可以減少屬性訪問的次數(shù),提高性能茅主。例如:
class Time {
static start: number = 0;
static info: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
}
function getNum(num: number): number {
let total: number = 348;
for (let index: number = 0x8000; index > 0x8; index >>= 1) {
// 此處會多次對Time的info及start進(jìn)行查找舞痰,并且每次查找出來的值是相同的
total += ((Time.info[num - Time.start] & index)!== 0)? 1 : 0;
}
return total;
}
// 優(yōu)化后代碼
function getNum(num: number): number {
let total: number = 348;
const info = Time.info[num - Time.start]; // 從循環(huán)中提取不變量
for (let index: number = 0x8000; index > 0x8; index >>= 1) {
if ((info & index)!== 0) {
total++;
}
}
return total;
}
三、函數(shù)
(一)建議使用參數(shù)傳遞函數(shù)外的變量
使用閉包會帶來額外的閉包創(chuàng)建和訪問開銷诀姚。在性能敏感場景中响牛,應(yīng)盡量使用參數(shù)傳遞函數(shù)外的變量來替代閉包。例如:
// 不推薦使用閉包的方式
let arr = [0, 1, 2];
function foo(): number {
return arr[0] + arr[1];
}
foo();
// 推薦使用參數(shù)傳遞變量
let arr = [0, 1, 2];
function foo(array: number[]): number {
return array[0] + array[1];
}
foo(arr);
(二)避免使用可選參數(shù)
函數(shù)的可選參數(shù)表示參數(shù)可能為undefined
赫段,在函數(shù)內(nèi)部使用該參數(shù)時呀打,需要進(jìn)行非空值的判斷,這會造成額外的開銷糯笙。因此贬丛,根據(jù)業(yè)務(wù)需求,應(yīng)將函數(shù)參數(shù)聲明為必須參數(shù)给涕,或者考慮使用默認(rèn)參數(shù)豺憔。例如:
// 不推薦使用可選參數(shù)
function add(left?: number, right?: number): number | undefined {
if (left!== undefined && right!== undefined) {
return left + right;
}
return undefined;
}
// 推薦使用默認(rèn)參數(shù)
function add(left: number = 0, right: number = 0): number {
return left + right;
}
四、數(shù)組
(一)數(shù)值數(shù)組推薦使用TypedArray
在涉及純數(shù)值計算的場景中够庙,推薦使用TypedArray
數(shù)據(jù)結(jié)構(gòu)恭应。它能夠提供更好的性能表現(xiàn)。例如:
// 優(yōu)化前
const arr1 = new Array<number>([1, 2, 3]);
const arr2 = new Array<number>([4, 5, 6]);
let res = new Array<number>(3);
for (let i = 0; i < 3; i++) {
res[i] = arr1[i] + arr2[i];
}
// 優(yōu)化后
const typedArray1 = new Int8Array([1, 2, 3]);
const typedArray2 = new Int8Array([4, 5, 6]);
let res = new Int8Array(3);
for (let i = 0; i < 3; i++) {
res[i] = typedArray1[i] + typedArray2[i];
}
(二)避免使用稀疏數(shù)組
當(dāng)運(yùn)行時分配超過1024大小的數(shù)組或者處理稀疏數(shù)組時耘眨,會采用hash
表的方式來存儲元素昼榛,這相比于用偏移訪問數(shù)組元素速度較慢。因此剔难,在代碼開發(fā)過程中胆屿,應(yīng)盡量避免數(shù)組變成稀疏數(shù)組。例如:
// 直接分配100000大小的數(shù)組偶宫,運(yùn)行時會處理成用hash表來存儲元素
let count = 100000;
let result: number[] = new Array(count);
// 創(chuàng)建數(shù)組后非迹,直接在9999處賦值,會變成稀疏數(shù)組
let result: number[] = new Array();
result[9999] = 0;
(三)避免使用聯(lián)合類型數(shù)組
應(yīng)避免在數(shù)值數(shù)組中混合使用整型數(shù)據(jù)和浮點(diǎn)型數(shù)據(jù)读宙,以及使用聯(lián)合類型數(shù)組彻秆。根據(jù)業(yè)務(wù)需求楔绞,將相同類型的數(shù)據(jù)放置在同一數(shù)組中结闸。例如:
// 不推薦的寫法
let arrNum: number[] = [1, 1.1, 2]; // 數(shù)值數(shù)組中混合使用整型數(shù)據(jù)和浮點(diǎn)型數(shù)據(jù)
let arrUnion: (number | string)[] = [1, 'hello']; // 聯(lián)合類型數(shù)組
// 推薦的寫法
let arrInt: number[] = [1, 2, 3];
let arrDouble: number[] = [0.1, 0.2, 0.3];
let arrString: string[] = ['hello', 'world'];
五、異常
避免頻繁拋出異常
創(chuàng)建異常時會構(gòu)造異常的棧幀酒朵,這會造成性能損耗桦锄。在性能敏感場景下,如for
循環(huán)語句中蔫耽,應(yīng)避免頻繁拋出異常结耀。例如:
// 優(yōu)化前
function div(a: number, b: number): number {
if (a <= 0 || b <= 0) {
throw new Error('Invalid numbers.')
}
return a / b
}
function sum(num: number): number {
let sum = 0
try {
for (let t = 1; t < 100; t++) {
sum += div(t, num)
}
} catch (e) {
console.log(e.message)
}
return sum
}
// 優(yōu)化后
function div(a: number, b: number): number {
if (a <= 0 || b <= 0) {
return NaN
}
return a / b
}
function sum(num: number): number {
let sum = 0
for (let t = 1; t < 100; t++) {
if (t <= 0 || num <= 0) {
console.log('Invalid numbers.')
}
sum += div(t, num)
}
return sum
}
通過遵循以上鴻蒙Next ArkTS高性能編程實(shí)踐中的各項建議留夜,開發(fā)者可以在實(shí)際開發(fā)中顯著提升應(yīng)用的性能表現(xiàn),為用戶帶來更加流暢和高效的使用體驗图甜。同時碍粥,不斷總結(jié)和運(yùn)用高性能編程技巧,也是打造優(yōu)質(zhì)應(yīng)用的重要環(huán)節(jié)黑毅。