Rumah  >  Artikel  >  hujung hadapan web  >  Jangan sekali-kali memanggil fungsi yang sama dua kali (dengan memoisasi)

Jangan sekali-kali memanggil fungsi yang sama dua kali (dengan memoisasi)

WBOY
WBOYasal
2024-07-31 07:42:121083semak imbas

Never call the same function twice (with memoization)

Jadi saya baru sahaja menemui konsep kecil yang menarik tentang hafalan ini.

Saya telah mula membaca artikel mengenainya dan berhenti sebaik sahaja saya menangkap ekor idea itu.

Kemudian saya memutuskan untuk memikirkan penyelesaian mudah dengan cara saya sendiri dan dengan cara saya memahaminya.

Jika anda tidak pernah mendengarnya, memoisasi ialah proses menyimpan hasil pelaksanaan fungsi, jadi anda boleh menariknya daripada cache kecil (atau tidak begitu) pada kali seterusnya anda menjalankan fungsi itu dengan hujah yang sama.

Sebenarnya ini boleh berguna untuk fungsi penggunaan sumber yang tinggi. Ia datang dengan kos menggunakan ruang tambahan sebagai cache. Tetapi ia boleh meningkatkan kelajuan kod anda dan pengalaman pengguna yang menggunakannya.

Saya telah bermain dengan kod JS sedikit dan datang dengan penyelesaian ini:

const memoize = fn => {
  const cache = {}
  return (...args) => {
    const fnKey = `${fn.name}(${args})`;
    if(!cache[fnKey]) {
      cache[fnKey] = fn(...args);
    }

    return cache[fnKey]
  };
}

Kemudian anda boleh menjalankannya seperti itu:

function _add(x, y) {
  console.log("function runs", x, y);
  return x + y;
}

const add = memoize(_add)

add(42, 69)
add(10, 15)
add(10, 15)

Itu membawa kepada pelaksanaan fungsi dua kali (panggilan 'tambah' #1 dan #2). Panggilan 'tambah' ketiga akan menggunakan cache kerana ia sama dengan panggilan #2.

'function runs' 42 69
'function runs' 10 15

Anda dapat melihat bahawa 'fungsi berjalan' 10 15 hanya dipanggil sekali. Ini kerana kali kedua kami memanggilnya, cache sedang digunakan.

Sekarang mari kita pecahkan dengan cepat apa yang berlaku di sini.

Dalam contoh ini kami menggunakan mekanisme penutupan untuk menyimpan cache.

const memoize = fn => {
  const cache = {}
  return () => {

  };
}

Ini membolehkan kami melontarkan hujah "fn", yang merupakan raja parti kerana ini adalah fungsi yang kami mahu kendalikan, ke bawah skop dan "mendengar" setiap pelaksanaannya.

Saya benar-benar telah menulisnya dengan cara yang paling mudah dan naif. Jadi kita akan menggunakan nama fungsi dengan argumen sebagai kunci cache, dan hasil pelaksanaannya sebagai nilai.

Ini bermakna, pelaksanaan itu:

add(2, 2)

Hasil dalam

// Our cache
{
  'add(2, 2)': 4
}

Nilai cache.

Saya tahu bahawa ini mungkin bukan cara yang betul untuk dilakukan "dengan cara yang betul". Tetapi idea latihan ini dan artikel bukanlah mengenai penyelesaian bebas kes selamat dan tepi yang diuji dengan baik.

Ini mengenai pembelajaran dan pelaksanaan mudah. Mengenai konsep. Jadi saya tidak menumpukan pada butiran pelaksanaan sekarang.

Sekarang, kita mula-mula memikirkan kunci untuk panggilan fungsi:

const memoize = fn => {
  const cache = {}
  return (...args) => {
    const fnKey = `${fn.name}(${args})`;
  };
}

Kami akan menggunakannya untuk menyimpan hasil pelaksanaan fungsi dalam cache.

Kemudian kami menyemak sama ada kunci ini (fnKey) sudah wujud. Jika tidak, kami menetapkan kunci dengan nilainya sebagai hasil daripada pelaksanaan fungsi yang diluluskan.

Pada akhirnya kami sentiasa mengembalikan hasil daripada cache. Jadi benar-benar pelaksanaan fungsi yang diluluskan untuk memoize kaedah sentiasa berakhir dengan penutupan (dalam objek "cache").

Kami hanya beroperasi dengan objek ini sekarang:

const memoize = fn => {
  const cache = {}
  return (...args) => {
    const fnKey = `${fn.name}(${args})`;
    if(!cache[fnKey]) {
      cache[fnKey] = fn(...args);
    }

    return cache[fnKey]
  };
}

Dan itu sahaja.

Sekarang saya akan pergi dan melihat bagaimana ia harus dilakukan "dengan betul". Tetapi jika anda rasa ini menarik, beritahu saya. Jika ada sesuatu yang tidak jelas atau salah dengan pendekatan ini (untuk citarasa anda), tinggalkan komen dan mari bercakap mengenainya.

Terima kasih, jumpa lagi!

Atas ialah kandungan terperinci Jangan sekali-kali memanggil fungsi yang sama dua kali (dengan memoisasi). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel sebelumnya:NodeJS + ROHCArtikel seterusnya:NodeJS + ROHC