PERF: Reduce memory allocation by Emoji.unicode_replacements.

Calling `Emoji.tonable_emojis` fetches from the cache but creates
a giant array each time it is called.

```
MemoryProfiler.report { Emoji.unicode_replacements }.pretty_print
```

Before:

```
Total allocated: 16560770 bytes (246364 objects)
Total retained:  784793 bytes (10624 objects)

allocated memory by gem
-----------------------------------
  10224581  activesupport-4.2.8
   3504241  hiredis-0.6.1
   1449466  discourse/app
    679314  2.4.1/lib
    419592  discourse/lib
    226720  redis-3.3.3
     56680  activerecord-4.2.8
       176  thread_safe-0.3.6
```

After:

```
Total allocated: 2127703 bytes (30556 objects)
Total retained:  798099 bytes (10735 objects)

allocated memory by gem
-----------------------------------
   1270762  discourse/app
    690149  2.4.1/lib
    106977  bootsnap-1.0.0
     48764  activesupport-4.2.8
      5266  logster-1.2.7
      2473  hiredis-0.6.1
      2056  redis-3.3.3
       840  discourse/lib
       240  activerecord-4.2.8
       176  thread_safe-0.3.6
```
This commit is contained in:
Guo Xiang Tan 2017-06-20 13:02:39 +09:00
parent 8dbe2c3ec4
commit 40ef5c4f14

View File

@ -118,6 +118,7 @@ class Emoji
return @unicode_replacements if @unicode_replacements
@unicode_replacements = {}
is_tonable_emojis = Emoji.tonable_emojis
db['emojis'].each do |e|
next if e['name'] == 'tm'
@ -126,7 +127,7 @@ class Emoji
next unless code
@unicode_replacements[code] = e['name']
if Emoji.tonable_emojis.include?(e['name'])
if is_tonable_emojis.include?(e['name'])
FITZPATRICK_SCALE.each_with_index do |scale, index|
toned_code = (code.codepoints.insert(1, scale.to_i(16))).pack("U*")
@unicode_replacements[toned_code] = "#{e['name']}:t#{index+2}"
@ -156,6 +157,7 @@ class Emoji
def self.lookup_unicode(name)
@reverse_map ||= begin
map = {}
is_tonable_emojis = Emoji.tonable_emojis
db['emojis'].each do |e|
next if e['name'] == 'tm'
@ -164,7 +166,7 @@ class Emoji
next unless code
map[e['name']] = code
if Emoji.tonable_emojis.include?(e['name'])
if is_tonable_emojis.include?(e['name'])
FITZPATRICK_SCALE.each_with_index do |scale, index|
toned_code = (code.codepoints.insert(1, scale.to_i(16))).pack("U*")
map["#{e['name']}:t#{index+2}"] = toned_code