簡體   English   中英

NodeJS如何加速這個數組創建函數

[英]NodeJS how to speed up this array creation function

很難給它一個好的標題來描述這是什么,但這是我想出的最好的。 無論如何,這只是創建了一副牌,然后取出底牌。 性能至關重要,因為它需要對這種新的套牌創建、洗牌和底牌移除進行數千次迭代。

創建牌組的速度非常快,但底牌移除功能對性能造成了巨大影響,因為我找不到任何簡單的方法來移除 JS 中的元素。

 const suits = ['s', 'h', 'd', 'c']; const remove = ['10s', '11s', '13h', '9c']; var deck = mkDeck(); shuffle(deck) rmvHole(); // Functions function rmvHole() { for (let i = 0; i < remove.length; i++) { const key = Object.keys(deck).find(key => deck[key] === remove[i]); deck[key] = null; } } function mkDeck() { let arr = []; for (let s = 0; s < 4; s++) { for (let i = 2; i < 15; i++) { arr.push(i + suits[s]); } } return arr; } function shuffle(a) { for (let i = a.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [a[i], a[j]] = [a[j], a[i]]; } return a; } console.log(deck);
 .as-console-wrapper { max-height: 100% !important; top: auto; }

由於deck應該是一個數組,你絕對不應該遍歷它的Object.keys - 相反,因為數組值都是基元,你可以用indexOfsplice標識索引,或者在該數組索引處設置項目為null如果那就是你想要的:

function rmvHole() {
    for (let i = 0, { length } = remove; i < length; i++) {
        const index = deck.indexOf(remove[i]);
        // deck.splice(index, 1);
        // deck[index] = null;
    }
}

(將索引設置為null實際上並沒有從數組中刪除元素,這就是為什么我認為您可能是想改為splice

 const suits = ['s', 'h', 'd', 'c']; const remove = ['10s', '11s', '13h', '9c']; var deck = mkDeck(); shuffle(deck) rmvHole(); // Functions function rmvHole() { for (let i = 0; i < remove.length; i++) { const index = deck.indexOf(remove[i]); deck[index] = null; } } function mkDeck() { let arr = []; for (let s = 0; s < 4; s++) { for (let i = 2; i < 15; i++) { arr.push(i + suits[s]); } } return arr; } function shuffle(a) { for (let i = a.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [a[i], a[j]] = [a[j], a[i]]; } return a; } console.log(deck);
 .as-console-wrapper { max-height: 100% !important; top: auto; }

如果西裝不會改變,那么到目前為止創建它的最快方法是沒有循環,只需對數組進行硬編碼:

function mkDeck() {
  return [
      '2s', '3s', '4s', '5s', '6s', '7s', '8s', '9s', '10s', '11s', '12s', '13s', '14s', 
      '2h', '3h', '4h', '5h', '6h', '7h', '8h', '9h', '10h', '11h', '12h', '13h', '14h', 
      '2d', '3d', '4d', '5d', '6d', '7d', '8d', '9d', '10d', '11d', '12d', '13d', '14d', 
      '2c', '3c', '4c', '5c', '6c', '7c', '8c', '9c', '10c', '11c', '12c', '13c', '14c', 
  ];
}

如果需要移除的卡片總是相同的,那么您可以簡單地將它們從該硬編碼數組中排除。

function mkDeck() {
  return [
      '2s', '3s', '4s', '5s', '6s', '7s', '8s', '9s',               '12s', '13s', '14s', 
      '2h', '3h', '4h', '5h', '6h', '7h', '8h', '9h', '10h', '11h', '12h',        '14h', 
      '2d', '3d', '4d', '5d', '6d', '7d', '8d', '9d', '10d', '11d', '12d', '13d', '14d', 
      '2c', '3c', '4c', '5c', '6c', '7c', '8c',       '10c', '11c', '12c', '13c', '14c', 
  ];
}

這會減少在甲板上循環多次。 所以你剩下的所有代碼是:

let deck = mkDeck();
shuffle(deck);

相反,如果要移除的卡片是動態的,那么在生成牌組時更容易排除它們,而不是之后再查找它們,這樣您只需在牌組上循環一次 - 生成時:

 const suits = ['s', 'h', 'd', 'c']; const remove = ['10s', '11s', '13h', '9c']; var deck = mkDeck(); console.log(deck); function mkDeck() { let arr = []; for (let s = 0; s < 4; s++) { for (let i = 2; i < 15; i++) { let card = i + suits[s]; //only add if it should be added if (!remove.includes(card)) { arr.push(card); } } } return arr; }

如果remove是一個對象{ '10s': true, '11s': true, '13h': true, '9c': true }; 或一組new Set(['10s', '11s', '13h', '9c']) 在任何一種情況下,查找都不需要為您生成的每張卡片遍歷整個數組。

deck是一個數組,所以你不需要Object.keys

function rmvHole() {
    remove.forEach(r => deck.splice(deck.indexOf(r), 1));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM