aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activesupport/CHANGELOG2
-rw-r--r--activesupport/lib/active_support/json/encoders/core.rb33
2 files changed, 19 insertions, 16 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG
index b1bba4055c..77f0a57bdb 100644
--- a/activesupport/CHANGELOG
+++ b/activesupport/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* Greatly increased performance of String.to_json, which speeds up RJS considerably on large pages, fixes #3473 [Shugo Maeda]
+
* Detect missing_constants calls from removed modules and fail accordingly. [Nicholas Seckar]
* Stop using defined? in Dependencies.qualified_const_defined? since defined? may invoke const_missing. [Nicholas Seckar]
diff --git a/activesupport/lib/active_support/json/encoders/core.rb b/activesupport/lib/active_support/json/encoders/core.rb
index 97f994ac9a..483471ee3e 100644
--- a/activesupport/lib/active_support/json/encoders/core.rb
+++ b/activesupport/lib/active_support/json/encoders/core.rb
@@ -16,24 +16,25 @@ module ActiveSupport
define_encoder NilClass do
'null'
end
+
+ ESCAPED_CHARS = {
+ "\010" => '\b',
+ "\f" => '\f',
+ "\n" => '\n',
+ "\r" => '\r',
+ "\t" => '\t',
+ '"' => '\"',
+ '\\' => '\\\\'
+ }
define_encoder String do |string|
- returning value = '"' do
- string.each_char do |char|
- value << case
- when char == "\010": '\b'
- when char == "\f": '\f'
- when char == "\n": '\n'
- when char == "\r": '\r'
- when char == "\t": '\t'
- when char == '"': '\"'
- when char == '\\': '\\\\'
- when char.length > 1: "\\u#{'%04x' % char.unpack('U').first}"
- else; char
- end
- end
- value << '"'
- end
+ '"' + string.gsub(/[\010\f\n\r\t"\\]/) { |s|
+ ESCAPED_CHARS[s]
+ }.gsub(/([\xC0-\xDF][\x80-\xBF]|
+ [\xE0-\xEF][\x80-\xBF]{2}|
+ [\xF0-\xF7][\x80-\xBF]{3})+/ux) { |s|
+ s.unpack("U*").pack("n*").unpack("H*")[0].gsub(/.{4}/, '\\\\u\&')
+ } + '"'
end
define_encoder Numeric do |numeric|