Модель кэша с двумя Qache, упомянутая в этой статье, относится к модели данных кэша в памяти.
Независимо от того, какой язык, возможно, вам понадобится поместить некоторые данные в память, чтобы избежать повторных операций и чтения. Наиболее распространенным сценарием является селектор jQuery. Выбор некоторых элементов DOM очень трудоемкий. Мы надеемся кэшировать эти данные без необходимости повторного трансляции дерева DOM каждый раз, когда мы звоним.
Сохраните, но должно быть количество! Вы не можете поместить все исторические данные в память. В конце концов, текущая емкость памяти все еще довольно жалкой. Даже если память достаточно велика, память, выделенная каждым потоком в теории, все еще ограничена.
Итак, вопрос в том, как мы можем эффективно кэшировать действительно полезные данные? Это включает в себя алгоритмы устранения, и необходимо устранить нежелательные данные, чтобы сохранить полезные данные.
Есть несколько общих идей:
FIFO: Это первая очередь, первая очередь, первые кэшированные данные, и была устранена в первую очередь. Эта модель используется в знаменитой структуре jQuery.
LRU: структура списка с двумя связанными, каждый раз, когда хранятся новые данные, они помещаются непосредственно в заголовке связанного списка; Данные, доступные каждый раз, также передаются в заголовок связанного списка. Таким образом, данные в конце связанного списка - это то, что не использовалось в последнее время и будут исключены.
ДВАКЕЙТ: FIFO+ LRU. FIFO в основном хранит данные, хранящиеся в первый раз, а LRU сохраняет данные горячей точки, которые использовались как минимум дважды. Этот алгоритм имеет высокую скорость попадания, сильную адаптивность и низкую сложность.
Есть много других алгоритмов устранения, но есть только два типа, которые используются больше на практике. Поскольку их алгоритмы не являются сложными, легко реализовать, высокая эффективность выполнения и скорость попадания в кэш приемлема в большинстве случаев. В конце концов, алгоритм кеша также требует потребления процессора. Если он слишком сложный, хотя скорость попадания была улучшена, это не стоит потери. Представьте себе, что если вы извлекаете данные из кэша, это занимает больше времени, чем извлечение из исходного местоположения. Что такое кеш?
Я не буду говорить о конкретных теориях. Есть некоторые онлайн, но я их мало понимаю. Сегодня я поделюсь с вами версией JavaScript Cache Model.
Давайте поговорим о том, как его использовать в первую очередь, это очень просто.
Основной метод использования следующим образом:
[/код]
var tq = inittwoqueues (10);
tq.set ("key", "value");
tq.get ("key");
[/код]
При инициализации просто укажите емкость кеша. Следует отметить, что, поскольку FIFO+LRU реализован внутри, фактическая емкость вдвое превышает указанную мощность. Приведенный выше пример указывает 10 (пары ключей), которые могут фактически сохранить 20.
Размер пропускной способности должен быть определен в соответствии с фактическим сценарием применения. Если он слишком мал, скорость попадания низкая, эффективность низкая, а крайность противоположна, и вам нужно измерить его самостоятельно.
В процессе разработки, чтобы рассмотреть эффект кэша, пул кэша может быть инициализирован в версию разработки:
Кода -копия выглядит следующим образом:
var tq = inittwoqueues (10, true);
tq.hitratio ();
Просто добавьте параметр к концу и просто верно. Пул кэша, инициализированный таким образом, автоматически подсчитывает скорость попадания, а скорость попадания может быть получена с помощью метода Hitratio. Если этот параметр не добавлен, скорость попадания, полученная методом Hitratio, всегда 0.
Статистический уровень попаданий определенно будет потреблять ресурсы, поэтому не рекомендуется включать в производственную среду.
Пришло время поделиться кодом:
Кода -копия выглядит следующим образом:
(функция (экспорт) {
/**
* Чистый класс для наследства
* @constructor
*/
Функция fn () {}
Fn.prototype = elmination.prototype;
/**
* Алгоритм устранения кэша родительского класса на основе связанного списка
* @param maxlength delength емкость
* @constructor
*/
Устранение функций (maxlength) {
this.container = {};
this.length = 0;
this.maxlength = maxlength || 30;
this.linkhead = this.buildnode ("", "," ");
this.linkhead.head = true;
this.linktail = this.buildNode ("", "" ");
this.linktail.tail = true;
this.linkhead.next = this.linktail;
this.linktail.prev = this.linkhead;
}
Elmination.prototype.get = function (key) {
Выбросить новую ошибку («Этот метод должен быть переопределяется!»);
};
Elmentimance.prototype.set = function (key, value) {
Выбросить новую ошибку («Этот метод должен быть переопределяется!»);
};
/**
* Создать узлы в связанном списке
* @param Данные данные, содержащиеся в узле, то есть к кэшированному значению данных
* @param Ключ Уникальный идентификатор узла, то есть кэшированный ключ
* @returns {{}}
*/
Elmentimance.prototype.buildnode = function (data, key) {
var node = {};
node.data = data;
node.key = key;
node.use = 0;
вернуть узел;
};
/**
* Узел появляется из заголовка связанного списка
* @returns {*}
*/
Elmentimance.prototype.shift = function () {
var node = null;
if (! this.linkhead.next.tail) {
node = this.linkhead.next;
this.linkhead.next = node.next;
node.next.prev = this.linkhead;
Удалить это.container [node.key];
this.length--;
}
вернуть узел;
};
/**
* Вставьте узел из заголовка связанного списка
* @param Узел Узел Узел
* @returns {*}
*/
Elmination.prototype.unshift = function (node) {
node.next = this.linkhead.next;
this.linkhead.next.prev = node;
this.linkhead.next = node;
node.prev = this.linkhead;
this.container [node.key] = node;
this.length ++;
вернуть узел;
};
/**
* Вставьте узел из конца связанного списка
* @param Узел Узел Узел
* @returns {*}
*/
Elmination.prototype.append = function (node) {
this.linktail.prev.next = node;
node.prev = this.linktail.prev;
node.next = this.linktail;
this.linktail.prev = node;
this.container [node.key] = node;
this.length ++;
вернуть узел;
};
/**
* Узел появляется с конца связанного списка
* @returns {*}
*/
Elmentimance.prototype.pop = function () {
var node = null;
if (! this.linktail.prev.head) {
node = this.linktail.prev;
node.prev.next = this.linktail;
this.linktail.prev = node.prev;
Удалить это.container [node.key];
this.length--;
}
вернуть узел;
};
/**
* Удалите указанный узел из связанного списка
* @param Узел Узел Узел
* @returns {*}
*/
Elmination.prototype.remove = function (node) {
node.prev.next = node.next;
node.next.prev = node.prev;
Удалить это.container [node.key];
this.length--;
вернуть узел;
};
/**
* Обработка, необходимая для того, чтобы выполнить, когда доступ к узлу, - это переместить узел в заголовок связанного списка
* @param Узел
*/
Elmentimance.prototype.use = function (node) {
this.remove (node);
this.unshift (узел);
};
/**
* Реализация алгоритма устранения кэша LRU
* @constructor
*/
функция lru () {
Elsomemance.apply (это, аргументы);
}
Lru.prototype = new fn ();
Lru.prototype.get = function (key) {
var node = undefined;
node = this.container [key];
if (node) {
this.use (узел);
}
вернуть узел;
};
Lru.prototype.set = function (key, value) {
var node = this.buildnode (значение, ключ);
if (this.length === this.maxlength) {
this.pop ();
}
this.unshift (узел);
};
/**
* Реализация алгоритма устранения кэша FIFO
* @constructor
*/
функция fifo () {
Elsomemance.apply (это, аргументы);
}
Fifo.prototype = new fn ();
Fifo.prototype.get = function (key) {
var node = undefined;
node = this.container [key];
вернуть узел;
};
Fifo.prototype.set = function (ключ, значение) {
var node = this.buildnode (значение, ключ);
if (this.length === this.maxlength) {
this.shift ();
}
this.append (узел);
};
/**
* Инкапсуляция алгоритма LRU и FIFO стала новым алгоритмом устранения кэша Twoeues
* @param maxlength
* @constructor
*/
Функциональный агент (maxlength) {
this.getCount = 0;
this.hitcount = 0;
this.lir = new fifo (maxlength);
this.hir = new lru (maxlength);
}
Agent.prototype.get = function (key) {
var node = undefined;
node = this.lir.get (key);
if (node) {
node.use ++;
if (node.use> = 2) {
this.lir.remove (node);
this.hir.set (node.key, node.data);
}
}еще{
node = this.hir.get (key);
}
вернуть узел;
};
Agent.prototype.getx = function (key) {
var node = undefined;
this.getCount ++;
node = this.get (key);
if (node) {
this.hitcount ++;
}
вернуть узел;
};
Agent.prototype.set = function (ключ, значение) {
var node = null;
node = this.lir.container [key] || this.hir.container [Key];
if (node) {
node.data = значение;
}еще{
this.lir.set (ключ, значение);
}
};
/**
* Получите высоту
* @returns {*}
*/
Agent.prototype.hitratio = function () {
var ret = this.getCount;
if (ret) {
ret = this.hitCount / this.getCount;
}
возврат возврата;
};
/**
* Внешний интерфейс
* @param maxlength delength емкость
* @param dev, будь то среда разработки, среда разработки будет подсчитывать скорость попадания, в противном случае она не будет
* @returns {{get, set: function, hitratio: function}}
*/
exports.inittwoqueues = function (maxlength, dev) {
var api = новый агент (maxlength);
возвращаться {
get: (function () {
if (dev) {
вернуть функцию (ключ) {
var ret = api.getx (key);
return ret && ret.data;
};
}еще{
вернуть функцию (ключ) {
var ret = api.get (key);
return ret && ret.data;
};
}
} ()),
set: function () {
api.set.apply (api, аргументы);
},
hitratio: function () {
вернуть api.hitratio.apply (api, аргументы);
}
};
};
}(этот));
Наконец, я хотел бы еще раз напомнить вам, что алгоритм кеша должен сочетаться с фактическими сценариями приложений. Без универсального алгоритма лучший из них лучший!