本地AI模型实现LRU 及其比较

gemma2(9.2b)

js 复制代码
class LRUCache {
  constructor(capacity) {
    this.capacity = capacity;
    this.cache = new Map();
  }

  get(key) {
    if (this.cache.has(key)) {
      const value = this.cache.get(key);
      this.moveToFront(key); // 将访问过的 key 移到最前面
      return value;
    }
    return -1; // 键不存在
  }

  put(key, value) {
    if (this.cache.has(key)) {
      this.cache.set(key, value);
      this.moveToFront(key); // 更新值后,将 key 移到最前面
    } else {
      if (this.cache.size >= this.capacity) {
        // 缓存已满,移除最不经常使用的项
        const oldestKey = this.getOldestKey();
        this.cache.delete(oldestKey);
      }
      this.cache.set(key, value);
    }
  }

  moveToFront(key) {
    // 将 key 移到最前面
    const value = this.cache.get(key);
    this.cache.delete(key);
    this.cache.set(key, value);
  }

  getOldestKey() {
    // 返回最不经常使用的 key
    return Array.from(this.cache.keys())[0];
  }
}

// 示例用法
const cache = new LRUCache(2);
cache.put(1, 1);
cache.put(2, 2);
console.log(cache.get(1)); // 返回 1
cache.put(3, 3); // 移除 key 2
console.log(cache.get(2)); // 返回 -1
cache.put(4, 4); // 移除 key 1
console.log(cache.get(1)); // 返回 -1
console.log(cache.get(3)); // 返回 3
console.log(cache.get(4)); // 返回 4
kotlin 复制代码
class LRUCache {
  constructor(capacity) {
    this.capacity = capacity;
    this.cache = new Map();
  }

  get(key) {
    if (this.cache.has(key)) {
      const value = this.cache.get(key);
      this.moveToFront(key); // 将访问过的 key 移到最前面
      return value;
    }
    return -1; // 键不存在
  }

  put(key, value) {
    if (this.cache.has(key)) {
      this.cache.set(key, value);
      this.moveToFront(key); // 更新值后,将 key 移到最前面
    } else {
      if (this.cache.size >= this.capacity) {
        // 缓存已满,移除最不经常使用的项
        const oldestKey = this.getOldestKey();
        this.cache.delete(oldestKey);
      }
      this.cache.set(key, value);
    }
  }

  moveToFront(key) {
    // 将 key 移到最前面
    const value = this.cache.get(key);
    this.cache.delete(key);
    this.cache.set(key, value);
  }

  getOldestKey() {
    // 返回最不经常使用的 key
    return Array.from(this.cache.keys())[0];
  }
}

// 示例用法
const cache = new LRUCache(2);
cache.put(1, 1);
cache.put(2, 2);
console.log(cache.get(1)); // 返回 1
cache.put(3, 3); // 移除 key 2
console.log(cache.get(2)); // 返回 -1
cache.put(4, 4); // 移除 key 1
console.log(cache.get(1)); // 返回 -1
console.log(cache.get(3)); // 返回 3
console.log(cache.get(4)); // 返回 4

解释:

  • LRUCache 类实现了一个容量为 capacity 的LRU 缓存。

  • cache 是一个 Map,用于存储键值对。

  • get(key) 方法:

    • 检查 key 是否存在于 cache 中。
    • 如果存在,则返回对应的值,并使用 moveToFront(key)key 移到最前面。
    • 如果不存在,则返回 -1
  • put(key, value) 方法:

    • 如果 key 已经存在,则更新对应的值并使用 moveToFront(key)key 移到最前面。

    • 如果 key 不存在:

      • 如果 cache 已满,则使用 getOldestKey() 获取最不经常使用的 key 并从 cache 中删除。
      • 将新的 keyvalue 添加到 cache 中。
  • moveToFront(key) 方法:

    • cache 中删除 key,然后将其重新添加到最前面。
  • getOldestKey() 方法:

    • 返回 cache 中的第一个键(即最不经常使用的键)。

phi3(3.8b)

js 复制代码
function LRUCache(capacity) {
  this.cache = []; // 存储元素的列表
  this.cacheMap = new Map(); // 存储元素及其索引关系
  this.capacity = capacity;
}

LRUCache.prototype.get = function(key) {
  if (this.cacheMap.has(key)) {
    let index = this.cacheMap.get(key);
    // 将该元素前移
    this.moveToFront(index);
    return this.cache[index];
  }
  return -1; // 返回-1表示不存在
};

LRUCache.prototype.put = function(key, value) {
  if (this.cacheMap.has(key)) {
    // 如果键已经在缓存中,则前移它到首位
    let index = this.cacheMap.get(key);
    this.moveToFront(index);
    this.cache[index] = value;
  } else {
    // 添加新元素
    if (this.cache.length >= this.capacity) {
      let leastRecentlyUsedKey = this.popLeastUsed();
      delete this.cacheMap.get(leastRecentlyUsedKey);
    }
    this.addToFront(key, value);
  }
};

LRUCache.prototype.remove = function(key) {
  if (this.cacheMap.has(key)) {
    let index = this.cacheMap.get(key);
    this.cache[index] = undefined; // 弹出元素值为undefined
    this.cacheMap.delete(key); // 从索引-值对象中删除
    if (this.cache.length < Math.ceil(this.capacity / 2)) {
      // 如果缓存容量低于一半的大小,则合并尾部元素与首部元素
      let lastIndex = this.cache.pop();
      if (lastIndex !== undefined) {
        delete this.cacheMap.get(this.cache[0]); // 删除首部元素对应索引-值对象中的关系
        this.addToFront(this.cache[lastIndex], this.cacheMap.keys().next().value);
      }
    }
  }
};

LRUCache.prototype.popLeastUsed = function() {
  if (this.cache.length === 0) return undefined; // 缓存为空时返回undefined
  let lastIndex = this.cache.length - 1;
  let leastRecentlyUsedKey = this.cache[lastIndex];
  delete this.cacheMap.get(leastRecentlyUsedKey);
  return leastRecentlyUsedKey; // 返回释放元素的索引
};

LRUCache.prototype.addToFront = function(key, value) {
  if (this.cache.length >= this.capacity) throw new Error('Capacity exceeded');
  this.cache.unshift(value); // 前移元素到首位
  let index = this.cache.length - 1;
  this.cacheMap.set(key, index); // 更新索引-值对象中关系
};

LRUCache.prototype.moveToFront = function(index) {
  if (this.cache.length <= index) throw new Error('Index out of range');
  let key = this.cache[index];
  this.remove(key); // 先移除以后再前移
  this.addToFront(key, this.cache[index]);
};

这个LRUCache类的主要方法包括:

  • get(key): 返回值对应于指定键的元素。如果没有查询到,则返回-1。
  • put(key, value): 将键值对存入缓存中,并根据最近使用到的规则移动元素。如果超过了容量限制,需要移除LRU(Least Recently Used)元素。
  • remove(key): 移除指定键对应的元素。

这个实现是简单且可以理解的,但在大规模或高性能场景下,可能需要更进一步的优化和改进。

llama3(8.0b)

kotlin 复制代码
class LRUCache {
  constructor(capacity) {
    this.capacity = capacity;
    this.cache = new Map();
    this.order = [];
  }

  get(key) {
    if (!this.cache.has(key)) return null;
    const value = this.cache.get(key);
    this.remove(key);
    this.add(key);
    return value;
  }

  set(key, value) {
    if (this.cache.size >= this.capacity) {
      const evictedKey = this.order.shift();
      this.cache.delete(evictiedKey);
    }
    this.cache.set(key, value);
    this.add(key);
  }

  remove(key) {
    if (!this.cache.has(key)) return;
    this.cache.delete(key);
    const index = this.order.indexOf(key);
    if (index !== -1) this.order.splice(index, 1);
  }

  add(key) {
    this.cache.set(key, null); // Update the cache entry
    this.order.push(key);
  }
}

总结

这几个模型生成的代码各有侧重,需根据背景选择使用。

相关推荐
吴文周6 小时前
告别重复劳动:一套插件让 AI 替你写代码、修Bug、做测试、上生产
前端·后端·ai编程
Mh6 小时前
我决定写一个 3D 地球仪来记录下我要去的地方
前端·javascript·动效
yaoxin5211236 小时前
390. Java IO API - WatchDir 示例
java·前端·python
懒狗小前端6 小时前
做了一个 codex 的中文文档网站,做的不好可以随便喷
前端·后端
. . . . .8 小时前
ref、useRef 和 forwardRef
前端·javascript·react.js
energy_DT8 小时前
2026年海上钻井平台数字孪生平台:引领海洋能源数字化转型
前端
Eric_见嘉8 小时前
在职前端 Agent 配置分享
前端·后端·agent
柚子8168 小时前
break跳出语句块的神奇技巧
前端·javascript
ejinxian9 小时前
Rust GUI框架Azul与Electron、WebView2
前端·javascript·electron
IT_陈寒10 小时前
Vue的v-for里用index当key,我被自己坑惨了
前端·人工智能·后端