国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JS前端千萬級彈幕數據循環優化示例

3403771864 / 534人閱讀

      大數據中時常都會有優化,這篇文章要和大家降的就是如何按照特定的條件刪除一個數組?

  1、如何刪除數組中的元素

  場景:有一個數組,需要刪除滿足條件的數組。

  示例:  

const arr = [1,2,3,4,5,6,7,8]

  刪除小于5的元素,刪除后的元素為

  const arr2 = [5, 6, 7, 8]

  代碼實現:

  const arr = [1,2,3,4,5,6,7,8]
  for(let i = 0, len = arr.length; i < len; i++) {
  if(arr[i] < 5) {
  arr.splice(i, 1)
  }
  }

  結果如下

  arr = [2, 4, 5, 6, 7, 8

  不是我們預期的結果

  分析原因:刪除操作會使得對應索引值位上的元素清空,整個數組中的元素向前移動一位,補位的元素會填充到執行刪除操作的索引值位置上,移位之后如果不進行任何操作繼續下一個循環,會導致補位元素跳過遍歷,為了防止這種補位元素跳過遍歷現象,應該在刪除操作后將索引值減1,對執行刪除操作的索引值位置再進行一次遍歷 。

  改進:

  const arr = [1,2,3,4,5,6,7,8]
  for(let i = 0, len = arr.length; i < len; i++) {
  if(arr[i] < 5) {
  arr.splice(i, 1)
  i--;
  }
  }
  // arr = [5, 6, 7, 8] 符合預期

  這個是做了正序循環刪除,也可以使用倒序循環刪除:

  const arr = [1,2,3,4,5,6,7,8]
  for(let i = arr.length - 1; i >= 0; i--) {
  if(arr[i] < 5) {
  arr.splice(i, 1)
  }
  }
  // arr = [5, 6, 7, 8] 符合預期

  2、當消息有10000,000條優化又如何?

  場景

  彈幕消息發送場景模擬(偽直播形式,沒有進度條):假設我們有10000,000條消息,根據視頻播放的進度展示對應的消息,不展示歷史消息。

  常規思路:

  循環遍歷整個消息列表,時刻監聽視頻播放的進度,根據視頻播放的時間戳和消息發送的時間戳先相等,然后展示消息,依次循環。

  產生的問題

  每次視頻進度變化都會循環整個消息列表,當循環還沒完成,下一個播放進度監聽觸發了,又開始下一個循環,這樣就會造成性能的損耗。

  優化策略

  我們從上面的分析可以看出,當消息發送了一條,就可以從原始數據刪除這條消息,然后跳出循環,這樣循環的次數始終控制在幾次(或者幾十次)的范圍(有可能同一個時間段同時有幾條消息甚至幾十條消息)等下一個播放進度監聽觸發,開始循環原始數據,這是之前以后發送過得數據刪除了,就不會再循環刪除過的數據,始終循環需要發送的那幾條,找到了就直接跳出循環。

  代碼實現

  // 模擬原始消息列表,
  const newList = new Array(10000000).fill(1).map((item, index) => {
  return {
  time: (index + 1) * 1000, // 消息發送的時間,一秒一個
  content: `這是第${index + 1}s發送的消息` // 消息發送的內容
  }
  })
  // 發送的消息列表
  const sendList = [];
  function getMessage(time) {
  let j = 0; // 循環次數
  for(let i = 0, len = newList.length; i < len; i++) {
  const item = newList[i];
  j++;
  // 這里的time如果不是1000、2000,而是1234、1214這種,就需要取一個浮動范圍
  // 我這里就是簡單用了定時器,所以比較簡單
  if(item.time === time) {
  sendList.push(newList[i])
  newList.splice(i, 1)
  i--;
  } else if(sendList.length > 0) {
  break;
  }
  }
  console.log('播放進度', time)
  console.log('循環的次數', j);
  console.log('接收的消息的長度', sendList.length, sendList);
  console.log('原始消息的長度', newList.length);
  }
  let time = 0;
  // 定時器,1s觸發一次
  setInterval(() => {
  time += 1000;
  getMessage(time);
  }, 1000)
  // 消息格式
  newList = [
  {time: 1000, content: '這是第1s發送的消息'},
  {time: 2000, content: '這是第2s發送的消息'},
  ...
  ]

  效果展示

1.png

  小結

  上述優化總的來說就是發送過的消息刪除,下次少循環。當找到滿足條件的數據,直接跳出循環,后面的數據不再循環。

  缺點就是使用slice也會消耗性能,不可取,并且操作繁瑣。

  下面來說說游標法代替splice

  我們這里不再使用slice的方案,設置一個游標,記錄循環的初始位置,下次循環直接從游標記錄的位置開始循環,然后滿足查找的條件就break,這樣既不破壞原來的數組,也能有效的減少循環的次數。

  let index = 0, sendList =[];
  function getMessage(time) {
  for(let i = 0, len = newList.length; i < len; i++) {
  const item = newList[i];
  // 這里的time如果不是1000、2000,而是1234、1214這種,就需要取一個浮動范圍
  // 我這里就是簡單用了定時器,所以比較簡單
  if(item.time === time) {
  index = i;
  sendList.push(newList[i])
  } else if(sendList.length > 0) {
  // 這里的查詢結束條件為,對應的時間范圍之外沒有消息了,并且需要發送的消息列表有消息,才break
  // 這里的結束條件想不到什么更好的方案了
  break;
  }
  }
  }

  上面我們只對視頻播放的時候做了優化,如果下次用戶進來進度直接接近尾聲了,這時候首次查找尾部消息的時候,就需要把前面所有的消息都循環一遍,所以還需要繼續優化。

  二分查找

  當首次加載的時候,采用二分法查找到消息開始的位置,當視頻播放的時候再根據查找到的index去循環消息體。

  function binarySearch(arr, time) {
  let upperBound = arr.length - 1; // 記錄長度
  let lowerBound = 0; // 記錄上次二分的位置
  let mid;
  // 切半分的位置 小于或等于 1就停止循環了
  while (lowerBound <= upperBound) {
  // (當前總長度 + 當前中間點位置長度) / 2 = 實際的中間點位置
  mid = Math.floor((upperBound + lowerBound) / 2);
  const item = arr[mid];
  const maxTime = time +500;
  const minTime = time + 500;
  // 當輸入的值大于中間值時,向后移動一位
  if (time > maxTime) {
  lowerBound = mid + 1;
  } else if (time < minTime) {
  // 當輸入值小于中間值時,向前移動一位
  upperBound = mid - 1;
  } else {
  return mid; // 找到指定數據位置
  }
  }
  return -1;
  }
  function findIndex(startPlayTime: number) {
  const searchIndex = binarySearch(this.messageList, time);
  // 賦值索引,用于快速發送消息
  if (searchIndex !== -1) {
  index = searchIndex;
  }
  }

  總結

  方法、方式都是在逐漸的優化,從最開始的splice方法,然后到后面的游標法和二分法,做了逐漸的優化。

  上述內容對于大家知識上可能不是非常重要,上面講的也是我們平時在寫代碼的時候,在日常寫代碼中也是在不斷的優化,也是一種negligible的提升,。例如,找leader去給你review代碼,就是讓我們在日常的工作業務中去不斷的提升自己的能力,讓自己成長。


文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/127570.html

相關文章

  • HTML5彈幕視頻播放器

    摘要:考慮到只適合在單位時間內繪制少量彈幕,這對于我們播放器來說明顯是不合需求的。比如說直播播放器模式和視頻播放器模式的優化細節又有點不一樣,還有高級彈幕的處理圖片,圖形等。。 前言 大家年前好,馬上就要元旦了,在很久沒有寫文章之后,想到這篇文章將會成為本人今年的絕響也是有點蛋疼。不過也好,畢竟本人算不得什么勤快的生物,而且比起那些大神來說也差遠了,就作為自己工作半年后的一次沉淀算了。 文中...

    happyfish 評論0 收藏0
  • HTML5彈幕視頻播放器

    摘要:考慮到只適合在單位時間內繪制少量彈幕,這對于我們播放器來說明顯是不合需求的。比如說直播播放器模式和視頻播放器模式的優化細節又有點不一樣,還有高級彈幕的處理圖片,圖形等。。 前言 大家年前好,馬上就要元旦了,在很久沒有寫文章之后,想到這篇文章將會成為本人今年的絕響也是有點蛋疼。不過也好,畢竟本人算不得什么勤快的生物,而且比起那些大神來說也差遠了,就作為自己工作半年后的一次沉淀算了。 文中...

    OBKoro1 評論0 收藏0

發表評論

0條評論

3403771864

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<