|
1 | 1 | 'use strict';
|
2 | 2 |
|
3 | 3 | const Iconv = require('iconv-lite');
|
| 4 | +const LRU = require('lru-cache').default; |
4 | 5 |
|
5 |
| -exports.decode = function(buffer, encoding, start, end, options) { |
| 6 | +const decoderCache = new LRU({ |
| 7 | + max: 500, |
| 8 | +}); |
| 9 | + |
| 10 | +exports.decode = function (buffer, encoding, start, end, options) { |
6 | 11 | if (Buffer.isEncoding(encoding)) {
|
7 | 12 | return buffer.toString(encoding, start, end);
|
8 | 13 | }
|
9 | 14 |
|
10 |
| - const decoder = Iconv.getDecoder(encoding, options || {}); |
| 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 | + } |
11 | 32 |
|
12 | 33 | const res = decoder.write(buffer.slice(start, end));
|
13 | 34 | const trail = decoder.end();
|
14 | 35 |
|
15 | 36 | return trail ? res + trail : res;
|
16 | 37 | };
|
17 | 38 |
|
18 |
| -exports.encode = function(string, encoding, options) { |
| 39 | +exports.encode = function (string, encoding, options) { |
19 | 40 | if (Buffer.isEncoding(encoding)) {
|
20 | 41 | return Buffer.from(string, encoding);
|
21 | 42 | }
|
|
0 commit comments