Re: Alphabets Benchmarks - How many ways to unaccent a text string? Turn AÄÁaäá into AAAaaa. And the winner is...
Gerald Bauer <[email protected]> Wed, 14 Aug 2019 02:41:20 +0200
| Newsgroups | gmane.comp.lang.ruby.general |
|---|---|
| Message-ID | <CAAxEZd_Jy3sHspJD-ryVTFaGLACTcXfURFQFEF7Dmdf52-44WA@mail.gmail.com> |
Hello,
Great thanks. Today I learned that String#gsub can take a Hash as
its second argument. I added your unaccent function.
About tr - that's great too and I guess that's as fast as you can
get - but unaccent will not work with ligatures e.g. 'æ'=>'ae', 'ß' =>
'ss' or german umlaut transliteration 'ä' => 'ae', 'ö' => 'oe' etc.
Some more new examples include - to quote from the updated readme [1]:
Samuel Williams writes in with one more optimization.
Why not replace the `NON_ALPHA_CHAR_REGEX`, that is, `/[^A-Za-z0-9 ]/`
with a regex matching only known accented chars?
``` ruby
UNACCENT_REGEX = Regexp.union( UNACCENT.keys )
def unaccent_gsub_v3b( text, mapping=UNACCENT, regex=UNACCENT_REGEX )
text.gsub( regex, mapping)
end
```
Hold on. Let's add some more optimizations to the humble `each_char`
version too.
For all 7-bit (less than 0x7F) unicode latin basic (also known as ascii)
char(acter)s no mapping (ever) needed. Let's try:
``` ruby
def unaccent_each_char_v2_7bit( text, mapping )
buf = String.new
text.each_char do |ch|
buf << if ch.ord < 0x7F
ch
else
mapping[ch] || ch
end
end
buf
end
```
Maybe the mapping lookup using an array index by an integer number
is faster than hash mapping lookup by single-character string?
Let's try:
``` ruby
UNACCENT_FASTER = UNACCENT.reduce( [] ) do |ary,(ch,value)|
ary[ ch.ord ] = value
ary
end
def unaccent_each_char_v2_7bit_faster( text, mapping_faster=UNACCENT_FASTER )
buf = String.new
text.each_char do |ch|
buf << if ch.ord < 0x7F
ch
else
mapping_faster[ ch.ord ] || ch
end
end
buf
end
```
Voila. And the winner is... Can you find a faster way? Show us.
Happy data (and text) wrangling with ruby. Cheers. Prost.
[1] https://github.com/sportdb/sport.db/tree/master/alphabets/benchmark
Unsubscribe: <mailto:[email protected]?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>