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

WBOY
Lepaskan: 2024-07-31 07:42:12
asal
1139 orang telah melayarinya

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]
  };
}
Salin selepas log masuk
Salin selepas log masuk

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)
Salin selepas log masuk

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
Salin selepas log masuk

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 () => {

  };
}
Salin selepas log masuk

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)
Salin selepas log masuk

Hasil dalam

// Our cache
{
  'add(2, 2)': 4
}
Salin selepas log masuk

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})`;
  };
}
Salin selepas log masuk

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]
  };
}
Salin selepas log masuk
Salin selepas log masuk

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!

sumber:dev.to
Kenyataan Laman Web ini
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
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan