Skip to content

Commit b716f5f

Browse files
authored
Merge pull request #1205 from EvilBeaver/feature/lru-cache-eval
Добавлен LRU-кэш для компилируемых Вычислить/Выполнить
2 parents a9b6e10 + d06319c commit b716f5f

File tree

2 files changed

+76
-3
lines changed

2 files changed

+76
-3
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*----------------------------------------------------------
2+
This Source Code Form is subject to the terms of the
3+
Mozilla Public License, v.2.0. If a copy of the MPL
4+
was not distributed with this file, You can obtain one
5+
at http://mozilla.org/MPL/2.0/.
6+
----------------------------------------------------------*/
7+
8+
using System;
9+
using System.Collections.Generic;
10+
11+
namespace ScriptEngine.Machine
12+
{
13+
public class LruCache<TKey, TValue>
14+
{
15+
private readonly int _capacity;
16+
17+
private readonly Dictionary<TKey, LinkedListNode<CacheItem>> _index =
18+
new Dictionary<TKey, LinkedListNode<CacheItem>>();
19+
20+
private readonly LinkedList<CacheItem> _list = new LinkedList<CacheItem>();
21+
22+
public LruCache(int capacity)
23+
{
24+
_capacity = capacity;
25+
}
26+
27+
public bool IsEmpty() => _index.Count == 0;
28+
29+
public void Clear()
30+
{
31+
_index.Clear();
32+
_list.Clear();
33+
}
34+
35+
public TValue GetOrAdd(TKey key, Func<TKey, TValue> factory)
36+
{
37+
if (_index.TryGetValue(key, out var listNode))
38+
{
39+
_list.Remove(listNode);
40+
_list.AddFirst(listNode);
41+
return listNode.Value.Value;
42+
}
43+
44+
if (_index.Count == _capacity)
45+
{
46+
var keyOfOld = _list.Last.Value.Key;
47+
_index.Remove(keyOfOld);
48+
_list.RemoveLast();
49+
}
50+
51+
var newItem = _list.AddFirst(CacheItem.Create(key, factory(key)));
52+
_index[key] = newItem;
53+
return newItem.Value.Value;
54+
}
55+
56+
private class CacheItem
57+
{
58+
public static CacheItem Create(TKey key, TValue value) =>
59+
new CacheItem(key, value);
60+
61+
private CacheItem(TKey key, TValue value)
62+
{
63+
Key = key;
64+
Value = value;
65+
}
66+
67+
public TKey Key { get; }
68+
69+
public TValue Value { get; }
70+
}
71+
}
72+
}

src/ScriptEngine/Machine/MachineInstance.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ public class MachineInstance
2424
private ExecutionFrame _currentFrame;
2525
private Action<int>[] _commands;
2626
private Stack<ExceptionJumpInfo> _exceptionsStack;
27-
27+
private LruCache<string, LoadedModule> _executeModuleCache = new LruCache<string, LoadedModule>(64);
28+
2829
private LoadedModule _module;
2930
private ICodeStatCollector _codeStatCollector;
3031
private MachineStopManager _stopManager;
@@ -200,7 +201,7 @@ public void PrepareDebugContinuation()
200201

201202
public IValue Evaluate(string expression, bool separate = false)
202203
{
203-
var code = CompileExpressionModule(expression);
204+
var code = _executeModuleCache.GetOrAdd(expression, CompileExpressionModule);
204205

205206
MachineInstance runner;
206207
MachineInstance currentMachine;
@@ -1431,7 +1432,7 @@ private void PopTmp(int arg)
14311432
private void Execute(int arg)
14321433
{
14331434
var code = _operationStack.Pop().AsString();
1434-
var module = CompileExecutionBatchModule(code);
1435+
var module = _executeModuleCache.GetOrAdd(code, CompileExecutionBatchModule);
14351436
PrepareCodeStatisticsData(module);
14361437

14371438
var frame = new ExecutionFrame();

0 commit comments

Comments
 (0)