Memoisasi — Performa Kode

Mar 02 2023
Apa itu Memoisasi? Memoisasi adalah teknik yang digunakan dalam pemrograman komputer untuk mengoptimalkan kinerja fungsi yang dipanggil berulang kali dengan argumen masukan yang sama. Idenya adalah untuk meng-cache hasil dari pemanggilan fungsi sebelumnya dan mengembalikan hasil yang di-cache alih-alih menghitung ulang hasil ketika fungsi dipanggil dengan argumen yang sama.

Apa itu Memoisasi?

Memoisasi adalah teknik yang digunakan dalam pemrograman komputer untuk mengoptimalkan kinerja fungsi yang dipanggil berulang kali dengan argumen masukan yang sama. Idenya adalah untuk meng-cache hasil dari pemanggilan fungsi sebelumnya dan mengembalikan hasil yang di-cache alih-alih menghitung ulang hasil ketika fungsi dipanggil dengan argumen yang sama.

Dalam JavaScript

Anda dapat mengimplementasikan memoisasi dengan membuat objek cache dan menggunakannya untuk menyimpan hasil pemanggilan fungsi sebelumnya. Berikut adalah contoh cara mengimplementasikan memoisasi dalam JavaScript:

function memoize(func) {
  const cache = {};
  return function(...args) {
    const key = JSON.stringify(args);
    if (cache[key]) {
      return cache[key];
    } else {
      const result = func.apply(this, args);
      cache[key] = result;
      return result;
    }
  };
}

Di dalam fungsi yang dikembalikan, kami membuat string keyyang digunakan JSON.stringifyuntuk membuat serial argumen input. Kami memeriksa apakah kunci ada di objek cache, dan jika ya, kami mengembalikan hasil yang di-cache. Jika tidak, kami memanggil fungsi asli dengan argumen masukan menggunakan applymetode, menyimpan hasilnya di objek cache, dan mengembalikan hasilnya.

Berikut adalah contoh cara menggunakan memoizefungsi untuk membuat memo fungsi Fibonacci sederhana:

const fibonacci = memoize(function(n) {
  if (n <= 1) {
    return n;
  } else {
    return fibonacci(n - 1) + fibonacci(n - 2);
  }
});

console.log(fibonacci(10)); // 55
console.log(fibonacci(10)); // 55 (cached result)

NodeJS + Redis = Peningkatan Kinerja

Node.js adalah runtime JavaScript sisi server yang menyediakan model pemrograman berbasis peristiwa asinkron. Redis adalah penyimpanan struktur data dalam memori sumber terbuka yang sering digunakan sebagai database, cache, dan perantara pesan. Di Node.js, Anda bisa menggunakan Redis untuk menyimpan dan mengambil data di memori, yang bisa membantu meningkatkan kinerja aplikasi Anda.

Berikut adalah contoh bagi Anda untuk memahami kinerja saat menggunakan teknik caching. Dan di bawah, kita akan beralih ke kode yang lebih praktis. Pertama, kita akan menginstal paket npm:

npm install express body-parser mongoose redis --save

const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const redis = require('redis');

const app = express();

app.use(bodyParser.json());

// connect to redis, use default port and address
const client = redis.createClient('redis://127.0.0.1:6379');
client.on("error", (err) => {
console.error(err);
});

// MongoDB connection
mongoose.connect('mongodb://localhost:27017/', {
dbName: 'notes',
useNewUrlParser: true,
useUnifiedTopology: true
}, err => err ? console.log(err) : console.log('Connected to database'));

// Mongoose Model
const NoteSchema = new mongoose.Schema({
title: String,
note: String
});

const Note = mongoose.model('Note', NoteSchema);

// api post a note
app.post('/api/notes', (req, res, next) => {const { title, note } = req.body;

const _note = new Note({
    title: title,
    note: note
});
// save to MongoDB
_note.save((err, note) => {
    if (err) {
        return res.status(404).json(err);
    }

    // If successful in MongoDB, then add it to Redis
    client.setex(note.id, 60, JSON.stringify(note), (err, reply) => {
        if (err) {
            console.log(err);
        }
        console.log(reply);
    });

    return res.status(201).json({
        message: 'Note has been saved',
        note: note
    });
})
});
const isCached = (req, res, next) => {
const { id } = req.params;

// First check in Redis
client.get(id, (err, data) => {
    if (err) {
        console.log(err);
    }
    if (data) {
        const response = JSON.parse(data);
        return res.status(200).json(response);
    }
    next();
});
}
// When retrieving, we will get it from Redis first instead of accessing MongoDB to get this data.
app.get('/api/notes/:id', isCached, (req, res, next) => {
const { id } = req.params;

Note.findById(id, (err, note) => {
    if (err) {
        return res.status(404).json(err);
    }
    return res.status(200).json({
        note: note
    });
});
});

app.listen(3000, () => console.log('Server running at port 3000'));

Pada baris kode di atas, kami memperhatikan pengaturan dan mendapatkan Redis:

client.setex(note.id, 60, JSON.stringify(note), (err, reply) => {
if (err) {
console.log(err);
}
console.log(reply);
});

detik: Waktu kedaluwarsa dalam detik sebagai angka.

nilai: Data aktual untuk disimpan di Redis. Itu harus berupa string. Jadi kami membuat serial objek menjadi string.

callback: Callback mengambil dua parameter err dan reply.

Dan saat mengambil dokumen, itu akan menuju ke isCached() untuk mengambilnya. Jika ada masalah, seperti waktu cache telah habis, maka Anda akan terus mengambil data di MongoDB.

app.get('/api/notes/:id', isCached, (req, res, next) => {

scss
Copy code
const { id } = req.params;

Note.findById(id, (err, note) => {
    if (err) {
        return res.status(404).json(err);
    }
    return res.status(200).json({
        note: note
    });
});
});