基于Id高效更新数组元素值的最优方案探讨
优化基于ID的数组批量更新方案(Socket游戏场景)
哥们,我完全懂你在Socket游戏里处理高频批量更新的痛点——几百个对象每秒多次更新,原来的双重遍历肯定会拖慢性能,咱们直接上最优解:
先拆解问题:原来的性能瓶颈
你当前的update函数用array1.forEach搭配array2.find,本质是双重线性遍历,时间复杂度是O(n*m)(n是array1长度,m是array2长度)。当数组规模上去,每秒跑好几次的话,这个开销会直接影响游戏流畅度。
最优方案:用哈希映射把查找复杂度降到O(1)
核心思路是先把array2转换成以id为键的映射表,这样后续更新array1时,直接通过id就能瞬间找到对应数据,不用再反复遍历整个array2。
修改后的完整代码
JavaScript部分
var array1 = [{ id:"asd4567wds8", x: 109, y: 763 }, { id:"df567wgfdz4", x: 450, y: 132 }, { id: "cvbz5476zzg", x: 903, y: 865 }] var array2 = [{ id:"df567wgfdz4", x: 450, y: 137 },{ id:"asd4567wds8", x: 114, y: 763 }, { id: "cvbz5476zzg", x: 908, y: 870 }] $(document).ready(function(){ display(); $("#update").click(function(){ update(); display(); }) }) // 优化后的update函数 function update(){ // 先把array2转成id->数据的映射,仅需遍历一次array2 const array2Map = {}; array2.forEach(item => { array2Map[item.id] = item; }); // 遍历array1,直接通过id从映射取数据更新 array1.forEach(element => { const updateData = array2Map[element.id]; if (updateData) { // 兜底判断,避免id不匹配时报错 element.x = updateData.x; element.y = updateData.y; } }); } function display(){ $("#Array1").empty().append("Array 1: "); $("#Array2").empty().append("Array 2: "); array1.forEach(function(element){ var p = $("<span>").text(`[${element.x}, ${element.y}] `) $("#Array1").append(p) }) array2.forEach(function(element){ var p = $("<span>").text(`[${element.x}, ${element.y}] `) $("#Array2").append(p) }) if(test(array1, array2)){ $("#test").text("Success!") } else { $("#test").text("Values do not match") } } /* Test function do not change */ function test(array1, array2){ var clear = true; array1.forEach(function(element){ var temp = array2.find(function(element2){ return element.id === element2.id }); clear = (element.x === temp.x && element.y === temp.y)?clear:false; }); return clear; }
HTML部分
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <body> <div id="Array1">Array 1: </div> <div id="Array2">Array 2: </div> <button id="update"> Update </button> <h3 id="test"></h3> </body>
为什么这个方案更高效?
- 时间复杂度从O(n*m)降到O(n+m):转换映射表仅需遍历一次array2(O(m)),更新array1仅需遍历一次array1(O(n)),数据量越大,性能提升越明显。
- 适配高频更新场景:每秒多次执行时,CPU开销会显著降低,不会因为遍历拖慢游戏帧率。
额外优化建议
如果你的游戏里array2是从Socket接收的批量数据,还可以:
- 直接在接收数据时就转换成映射表,不用每次
update都重复转换 - 如果需要处理
array2里有array1不存在的新对象,可以在update时判断并添加到array1里(根据业务需求调整)
内容的提问来源于stack exchange,提问作者Michael Sorensen
相关产品推荐
相关产品推荐

