|
1 | 1 | 'use strict'; |
2 | 2 |
|
3 | 3 | const Iconv = require('iconv-lite'); |
4 | | -const decoderCache = new Map(); |
| 4 | +const LRU = require('lru-cache'); |
| 5 | + |
| 6 | +const decoderCache = new LRU({ |
| 7 | + max: 500, |
| 8 | +}); |
5 | 9 |
|
6 | 10 | exports.decode = function (buffer, encoding, start, end, options) { |
7 | 11 | if (Buffer.isEncoding(encoding)) { |
8 | 12 | return buffer.toString(encoding, start, end); |
9 | 13 | } |
10 | 14 |
|
11 | | - const decoderArgs = { encoding, options: options || {} }; |
12 | | - const decoder = |
13 | | - decoderCache.get(decoderArgs) || |
14 | | - decoderCache |
15 | | - .set( |
16 | | - decoderArgs, |
17 | | - Iconv.getDecoder(decoderArgs.encoding, decoderArgs.options), |
18 | | - ) |
19 | | - .get(decoderArgs); |
| 15 | + // Optimize for common case: encoding="short_string", options=undefined. |
| 16 | + let decoder; |
| 17 | + if (!options) { |
| 18 | + decoder = decoderCache.get(encoding); |
| 19 | + if (!decoder) { |
| 20 | + decoder = Iconv.getDecoder(encoding); |
| 21 | + decoderCache.set(encoding, decoder); |
| 22 | + } |
| 23 | + } else { |
| 24 | + const decoderArgs = { encoding, options }; |
| 25 | + const decoderKey = JSON.stringify(decoderArgs); |
| 26 | + decoder = decoderCache.get(decoderKey); |
| 27 | + if (!decoder) { |
| 28 | + decoder = Iconv.getDecoder(decoderArgs.encoding, decoderArgs.options); |
| 29 | + decoderCache.set(decoderKey, decoder); |
| 30 | + } |
| 31 | + } |
20 | 32 |
|
21 | 33 | const res = decoder.write(buffer.slice(start, end)); |
22 | 34 | const trail = decoder.end(); |
|
0 commit comments