如何优化多评分JSON数据的平均评分计算性能?
优化评分计算代码的性能问题
当前这段代码可以正确计算出评分结果,但遍历逻辑存在可优化空间,同时缺少空数组的边界处理:
let totalReviewCount = updatedReviewData.length; let totalSchoolRating = 0; let totalAccomodationRating = 0; for (const item of updatedReviewData) { totalSchoolRating += item.avgSchoolRating; totalAccomodationRating += item.avgAccomodationRating; } const avgSchoolRating = totalSchoolRating / totalReviewCount; const avgAccomodationRating = totalAccomodationRating / totalReviewCount; const avgRating = (avgSchoolRating + avgAccomodationRating) / 2; // Calculate the overall average rating
数据示例:
[ { "review_date": "2023-09-05", "avgUserRating": 3.5, "avgSchoolRating": 3, "id": "e98c53fb-e272-4ca2-9f48-2a7930ecdaec", "accomodation_evaluation": { "accomodation_cleanliness_evaluation": 4, "accomodation_equipment_evaluation": 4, "accomodation_improvementContent": "test", "accomodation_otherContent": "test", "accomodation_reviewContent": "test", "accomodation_size_evaluation": 4 }, "avgAccomodationRating": 4, "school_evaluation": { "activity_evaluation": 3, "equipment_evaluation": 3, "improvementContent": "test", "instructor_evaluation": 3, "location_evaluation": 3, "otherContent": "test", "reviewContent": "test", "support_evaluation": 3 }, "school_id": "64a77e25-33a7-43c3-8221-259f6b5cc7e9" }, { "review_date": "2023-09-05", "avgUserRating": 3.5, "avgSchoolRating": 3, "id": "e98c53fb-e272-4ca2-9f48-2a7930ecdaec", "accomodation_evaluation": { "accomodation_cleanliness_evaluation": 4, "accomodation_equipment_evaluation": 4, "accomodation_improvementContent": "test", "accomodation_otherContent": "test", "accomodation_reviewContent": "test", "accomodation_size_evaluation": 4 }, "avgAccomodationRating": 4, "school_evaluation": { "activity_evaluation": 3, "equipment_evaluation": 3, "improvementContent": "test", "instructor_evaluation": 3, "location_evaluation": 3, "otherContent": "test", "reviewContent": "test", "support_evaluation": 3 }, "school_id": "64a77e25-33a7-43c3-8221-259f6b5cc7e9" } ]
优化方案
1. 补全边界处理
原代码未考虑数组为空的情况,此时会出现除以0导致的NaN结果,必须先做判断:
2. 简化遍历逻辑(可读性优先)
使用Array.reduce()在单次遍历中完成两个总和的计算,代码更简洁,性能与for...of相当,但可读性更好:
const totalReviewCount = updatedReviewData.length; // 空数组直接返回默认值,避免NaN if (totalReviewCount === 0) { return { avgSchoolRating: 0, avgAccomodationRating: 0, avgRating: 0 }; } const { totalSchoolRating, totalAccomodationRating } = updatedReviewData.reduce((acc, item) => { acc.totalSchoolRating += item.avgSchoolRating; acc.totalAccomodationRating += item.avgAccomodationRating; return acc; }, { totalSchoolRating: 0, totalAccomodationRating: 0 }); const avgSchoolRating = totalSchoolRating / totalReviewCount; const avgAccomodationRating = totalAccomodationRating / totalReviewCount; const avgRating = (avgSchoolRating + avgAccomodationRating) / 2;
3. 极端大数据量下的性能优化(性能优先)
如果数据量达到十万级以上,for...of的迭代器开销会显现,此时改用原生for循环能获得更优性能:
const totalReviewCount = updatedReviewData.length; if (totalReviewCount === 0) { return { avgSchoolRating: 0, avgAccomodationRating: 0, avgRating: 0 }; } let totalSchoolRating = 0; let totalAccomodationRating = 0; // 原生for循环减少迭代器开销 for (let i = 0; i < totalReviewCount; i++) { const item = updatedReviewData[i]; totalSchoolRating += item.avgSchoolRating; totalAccomodationRating += item.avgAccomodationRating; } const avgSchoolRating = totalSchoolRating / totalReviewCount; const avgAccomodationRating = totalAccomodationRating / totalReviewCount; const avgRating = (avgSchoolRating + avgAccomodationRating) / 2;
4. 超大数据量的进阶优化
如果数据量极大(百万级以上),可以考虑使用Web Worker在后台线程处理计算,避免阻塞主线程,不过这种场景在前端业务中较为罕见。
内容的提问来源于stack exchange,提问作者Lemon Kazi
相关产品推荐
相关产品推荐

