使用可变宽度编码的Ruby字符串索引

使用可变宽度编码的Ruby字符串索引,ruby,string,encoding,utf-8,Ruby,String,Encoding,Utf 8,这个问题与固定宽度(即UTF-32)与(即UTF-8)编码字符串的性能有关 特别是,如果我有一个包含1024个字符(不是字节,字符)的Ruby字符串,并且想要获得第1000个字符,它是否必须从字符串的开头开始读取,并查看每个前置单元,以知道在到达下一个字符之前要扫描多少字节? 如果你不确定我在说什么,我会很好地解释这一点 我做了一个基准测试,看看索引到一个特定字符串的字符需要多长时间,下面列出了源代码和结果。注意,我同时使用了a和渥以确保我有一个领导单元的情况 require 'benchmar

这个问题与固定宽度(即UTF-32)与(即UTF-8)编码字符串的性能有关

特别是,如果我有一个包含1024个字符(不是字节,字符)的Ruby字符串,并且想要获得第1000个字符,它是否必须从字符串的开头开始读取,并查看每个前置单元,以知道在到达下一个字符之前要扫描多少字节?

如果你不确定我在说什么,我会很好地解释这一点

我做了一个基准测试,看看索引到一个特定字符串的字符需要多长时间,下面列出了源代码和结果。注意,我同时使用了a以确保我有一个领导单元的情况

require 'benchmark'

def my_test(encoding, character)
  str = (character * 1024).encode(encoding)
  result =  Benchmark.measure { 
    (1..1000000).each do 
      str[1000]
    end
  }
  puts "Encoding: #{encoding.ljust(10)}  Character: #{character.ljust(2)}   Seconds: #{result}"
end

my_test 'UTF-8', 'a'
my_test 'UTF-16', 'a'
my_test 'UTF-32', 'a'
my_test 'Shift_JIS', 'a'
my_test 'US-ASCII', 'a'
my_test 'IBM437', 'a'

puts "------------"

my_test 'UTF-8', '渥'
my_test 'UTF-16', '渥'
my_test 'UTF-32', '渥'
my_test 'Shift_JIS', '渥'
结果:

请注意,UTF-8在独身领域比UTF-16/32略胜一筹,但在领导单元领域则需要更长的时间。

您在这里用存储换取速度,因此结果并不令人惊讶。我只会在你连续数百万次做深度子串的时候才关心这个问题。UTF-32的内存开销是相当大的。企业界的典型反应是尽可能地优化,然后向它扔一台速度更快的机器,以加快成本太高而无法优化的速度。在大多数地方,机器很便宜,程序员的时间也不多。@tadman我同意UTF-32存储在与我们打交道时要大得多。在我的例子中,我更关注CJK(中文、日文、韩文)字符,其中许多字符在UTF-8中需要3个字节,在UTF-16中只需要2个字节。话虽如此,您对RubyOnRails场景中UTF-16胜过UTF-8有何看法?我特别说的是“RubyOnRails”场景最终需要将数据传送到浏览器,页面的大部分是HTML/JavaScript/CSS(它们都适合UTF-8单例,从而将数据传输减半)。思想?