Commit Graph

7499 Commits

Author SHA1 Message Date
Jonathan Hefner
13f0ff9dfe Document increment order for {Date,etc}#advance [ci-skip] 2023-01-08 15:47:31 -06:00
Jonathan Hefner
ce23110829 Coordinate FilterParameters and ParameterFilter docs [ci-skip]
This clarifies the `ActiveSupport::ParameterFilter` documentation, and
tweaks the example code to be more friendly to the syntax highlighter
(similar to the tweaks made for `ActionDispatch::Http::FilterParameters`
in 782bed5d450363b302e0e6aa28b7ea0aef306d9f).

This also trims the `ActionDispatch::Http::FilterParameters`
documentation, and links it to `ActiveSupport::ParameterFilter`, since
`ActiveSupport::ParameterFilter` is responsible for filter behavior.
2023-01-08 15:47:20 -06:00
Jonathan Hefner
a4528b58e9 Reference AS::Deprecation instance methods [ci-skip]
This is in line with transitioning away from the global
`ActiveSupport::Deprecation` instance, towards individual
`ActiveSupport::Deprecation` instances.
2023-01-08 15:47:20 -06:00
Jonathan Hefner
cfe300ceb1 Format inline code [ci-skip] 2023-01-08 15:47:20 -06:00
Jonathan Hefner
3eadf057db Fix typos in API docs [ci-skip] 2023-01-08 15:47:20 -06:00
Jonathan Hefner
33557c5dca Indent private methods in code examples [ci-skip]
This matches the indentation used in generated code, such as code from
`railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt`.
2023-01-08 15:47:20 -06:00
Jean Boussier
05acc18d73
Merge pull request #46863 from ghiculescu/assert-diffrence-message
Include amount changed by in `assert_difference` failure message
2023-01-07 19:14:15 +01:00
zzak
13fecbd5a9 Use +symbol+ when there is no spaces or other breaking chars for RDoc 2023-01-07 09:23:11 +09:00
Alex Ghiculescu
293349c959 Include amount changed by in assert_difference failure message
Unless you're very good at math, this test fail message is not the easiest to debug:

```
"User.count" didn't change by 32.
Expected: 1611
  Actual: 1579
```

It's not obvious from the error, but in this case, it actually changed by 0. This is a pretty strong clue as to what went wrong, but the message doesn't tell us that.

This PR improves the message to make debugging easier:

```
"User.count" didn't change by 32 (changed by 0).
Expected: 1611
  Actual: 1579
```
2023-01-06 12:25:34 -07:00
Akira Matsuda
3d00c8b97f
Optimize camelize for single word
"hello"
Warming up --------------------------------------
                 old   101.269k i/100ms
                 new   193.263k i/100ms
Calculating -------------------------------------
                 old      1.073M (± 1.0%) i/s -      5.367M in   5.000337s
                 new      1.970M (± 1.0%) i/s -      9.856M in   5.002860s

Comparison:
                 new:  1970358.7 i/s
                 old:  1073491.6 i/s - 1.84x  (± 0.00) slower

"active_record"
Warming up --------------------------------------
                 old    45.864k i/100ms
                 new    44.306k i/100ms
Calculating -------------------------------------
                 old    468.932k (± 1.6%) i/s -      2.385M in   5.087160s
                 new    453.549k (± 1.4%) i/s -      2.304M in   5.080705s

Comparison:
                 old:   468931.7 i/s
                 new:   453549.3 i/s - 1.03x  (± 0.00) slower

"foo_bar_baz/aa_bb_cc"
Warming up --------------------------------------
                 old    18.536k i/100ms
                 new    18.334k i/100ms
Calculating -------------------------------------
                 old    186.371k (± 1.1%) i/s -    945.336k in   5.072959s
                 new    183.743k (± 0.9%) i/s -    935.034k in   5.089229s

Comparison:
                 old:   186371.2 i/s
                 new:   183742.5 i/s - same-ish: difference falls within error
2023-01-07 03:20:56 +09:00
Akira Matsuda
3ade331e75
This has to be mutable now... 2023-01-07 02:17:20 +09:00
Akira Matsuda
ca0d6521b1
tags_text() can actually be nil... 2023-01-07 01:59:26 +09:00
Akira Matsuda
0671acfeea
Reuse the String object created via tags_text()
tags_text() always creates a new mutable String
2023-01-07 01:56:05 +09:00
Akira Matsuda
c9875d31cc
Make it clear that SB#[]= takes 3 arguments, and reduce Array allocation
this reduces a redundant Array allocation that used to be created by *.
Plus, added some tests for []= with three arguments.
2023-01-06 03:02:02 +09:00
Akira Matsuda
5653d7d56d
String#* takes one argument, and in that case, better not splat the arg
because splatting the argument allocates an extra Array object.

benchmark
```ruby
s = 'a'.html_safe
Benchmark.ips do |x|
  x.report('') { s * 1 }
end
```

result
```
before
Warming up --------------------------------------
                       216.816k i/100ms
Calculating -------------------------------------
                          2.341M (± 2.0%) i/s -     11.708M in   5.002555s

after
Warming up --------------------------------------
                       315.118k i/100ms
Calculating -------------------------------------
                          3.704M (± 1.5%) i/s -     18.592M in   5.020261s
```
2023-01-05 10:15:19 +09:00
Akira Matsuda
aa73d1ad52
Method redefinition is no longer in use here
it's gone to another file via 9f5dee3a916a762a30efc472b52c613eb8979c5d,
then removed via d6c42b3fba456d1882682a5348610309164b1edd
2023-01-05 06:34:27 +09:00
Akira Matsuda
076003d8e6
require erb at the place where ERB is in use
follows up 9f5dee3a916a762a30efc472b52c613eb8979c5d
2023-01-05 06:30:31 +09:00
Eileen M. Uchitelle
2370ad1121
Merge pull request #46887 from zarqman/fix-deprec-msg
LogSubscriber: Fix example syntax for `color` in deprecation message
2023-01-04 15:04:56 -05:00
Akira Matsuda
ffdbf17191
Improve demodulize performance by not allocating a Range object
Warming up --------------------------------------
                 old   580.381k i/100ms
                 new   803.836k i/100ms
Calculating -------------------------------------
                 old      7.347M (± 0.9%) i/s -     37.144M in   5.056194s
                 new     10.640M (± 0.9%) i/s -     53.857M in   5.061897s

Comparison:
                 new: 10640489.8 i/s
                 old:  7346918.8 i/s - 1.45x  (± 0.00) slower
2023-01-05 04:32:04 +09:00
thomas morgan
2017c272f7 LogSubscriber: Fix example syntax for color in deprecation message 2023-01-04 12:19:02 -07:00
Akira Matsuda
a1c4aa87b3
Reduce two Array allocations 2023-01-05 02:15:10 +09:00
fatkodima
767ecc4131 Add ability to match exception messages to assert_raises assertion 2023-01-03 20:57:08 +02:00
Akira Matsuda
f6dbed5de4
HWIA#transform_values may take no argument
because Hash#transform_values! takes no argument and so raises when delegating
with the given arguments.

{}.with_indifferent_access.transform_values!(1) { p :hello }
 => wrong number of arguments (given 1, expected 0) (ArgumentError)
2023-01-01 21:57:41 +09:00
Hartley McGuire
ba2e06aee9
Use precompute optimization for Rails.env.local?
Ref: 09e0372

This makes #local? behave the same as the predefined environment
predicates (they immediately return a precomputed instance variable).

Benchmark:

```ruby
dev = ActiveSupport::EnvironmentInquirer.new("development")
test = ActiveSupport::EnvironmentInquirer.new("test")
prod = ActiveSupport::EnvironmentInquirer.new("production")

Benchmark.ips do |x|
  x.report("dev local?") { dev.local? }
  x.report("test local?") { test.local? }
  x.report("prod local?") { prod.local? }
  x.compare!
end
```

Before:
```
Warming up --------------------------------------
          dev local?   676.645k i/100ms
         test local?   627.687k i/100ms
         prod local?   671.078k i/100ms
Calculating -------------------------------------
          dev local?      6.785M (± 1.8%) i/s -     34.509M in   5.087679s
         test local?      6.284M (± 2.0%) i/s -     32.012M in   5.096338s
         prod local?      6.759M (± 1.8%) i/s -     34.225M in   5.065240s

Comparison:
          dev local?:  6785134.0 i/s
         prod local?:  6759023.6 i/s - same-ish: difference falls within error
         test local?:  6283910.1 i/s - 1.08x  (± 0.00) slower
```

After:
```
Warming up --------------------------------------
          dev local?     1.076M i/100ms
         test local?     1.049M i/100ms
         prod local?     1.028M i/100ms
Calculating -------------------------------------
          dev local?     10.586M (± 2.3%) i/s -     53.799M in   5.084729s
         test local?     10.350M (± 2.5%) i/s -     52.457M in   5.071399s
         prod local?     10.396M (± 2.2%) i/s -     52.422M in   5.045193s

Comparison:
          dev local?: 10586400.1 i/s
         prod local?: 10395758.6 i/s - same-ish: difference falls within error
         test local?: 10350328.8 i/s - same-ish: difference falls within error
```
2022-12-26 18:26:59 -05:00
Jonathan Hefner
4c4f4c385a Avoid double JSON parse for metadata-less messages
In #46612, a check was added to only attempt metadata extraction if the
message looks like a JSON object (i.e. starts with "{"), thus avoiding
an unnecessary JSON parse and possible exception.

This commit extends the check to only attempt metadata extraction if the
message looks like a metadata wrapper object (i.e. has the "_rails"
key).  This avoids an unnecessary JSON parse of JSON object messages
that don't have metadata.

**Benchmark**

  ```ruby
  require "benchmark/ips"
  require "active_support/all"

  verifier = ActiveSupport::MessageVerifier.new("secret", serializer: JSON)
  message_100 = verifier.generate({ content: "x" * 100 })
  message_1m = verifier.generate({ content: "x" * 1_000_000 })

  Benchmark.ips do |x|
    x.report("100 chars") do
      verifier.verify(message_100)
    end

    x.report("1m chars") do
      verifier.verify(message_1m)
    end
  end
  ```

**Before**

  ```
  Warming up --------------------------------------
             100 chars     2.803k i/100ms
              1m chars     6.000  i/100ms
  Calculating -------------------------------------
             100 chars     27.762k (± 1.6%) i/s -    140.150k in   5.049649s
              1m chars     83.516  (±16.8%) i/s -    402.000  in   5.037269s
  ```

**After**

  ```
  Warming up --------------------------------------
             100 chars     3.360k i/100ms
              1m chars     9.000  i/100ms
  Calculating -------------------------------------
             100 chars     33.480k (± 1.7%) i/s -    168.000k in   5.019311s
              1m chars    113.373  (±15.0%) i/s -    549.000  in   5.023443s
  ```
2022-12-21 14:12:15 -06:00
David Heinemeier Hansson
47eaf8881c
Add Rails.env.local? (#46786)
* Add Rails.env.local?

So many checks against Rails.env is whether we're running test or development, so combine into just one.

* Add CHANGELOG

* Prevent 'local' from being used as an environment name

Now that we have it as a combined predicate for dev + test.
2022-12-21 15:38:33 +01:00
David Heinemeier Hansson
2e142d9ae0 Explain the optimization setup 2022-12-21 14:51:02 +01:00
Hartley McGuire
daff36c157
Eager autoload ActiveSupport::ExecutionContext
ExecutionContext was added as a regular autoload when it was introduced
in 6bad959. However, the class is not currently referenced anywhere on
the boot path. This means that the file will currently be required
during the first request/job/query (currently its loaded when the to_run
callback defined in active_support.reset_execution_context is executed).

To maximize CoW and ensure that the first request/job/query doesn't have
any extra latency, ExecutionContext should be eager autoloaded instead.
2022-12-19 19:51:52 -05:00
Jonathan Hefner
61f711a1ff Support Message{Encryptors,Verifiers}#rotate block
This commit adds a block form of `ActiveSupport::MessageEncryptors#rotate`
and `ActiveSupport::MessageVerifiers#rotate`, which supports
fine-grained per-salt rotation options.  The block will receive a salt,
and should return an appropriate options Hash.  The block may also
return `nil` to indicate that the rotation does not apply to the given
salt.  For example:

  ```ruby
  verifiers = ActiveSupport::MessageVerifiers.new { ... }
  verifiers.rotate(serializer: JSON, url_safe: true)
  verifiers.rotate do |salt|
   case salt
   when :foo
     { serializer: Marshal, url_safe: true }
   when :bar
     { serializer: Marshal, url_safe: false }
   end
  end

  # Uses `serializer: JSON, url_safe: true`.
  # Falls back to `serializer: Marshal, url_safe: true`.
  verifiers[:foo]

  # Uses `serializer: JSON, url_safe: true`.
  # Falls back to `serializer: Marshal, url_safe: false`.
  verifiers[:bar]

  # Uses `serializer: JSON, url_safe: true`.
  verifiers[:baz]
  ```

This can be particularly useful when migrating older configurations to a
unified configuration.
2022-12-19 16:35:20 -06:00
Jonathan Hefner
f15e576467
Merge pull request #46755 from jonathanhefner/messages-rotation_coordinator-transitional
Add `Message{Encryptors,Verifiers}#transitional`
2022-12-19 16:34:30 -06:00
Ian Ker-Seymer
d4893067c5 Peek message before attempting to deserialize ActiveSupport::Message::Metadata using JSON
Rescuing an exception here can be wildly expensive here. We noticed 22ms overhead
on each request when attempting to decode metadata that was serialized using Marshal.

Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
2022-12-19 12:45:37 -06:00
Akira Matsuda
3baffd31be
Optimize for the default case where TaggedLogger takes only one tag name 2022-12-17 17:08:33 +09:00
Akira Matsuda
b9beb3eee1
Optimize for the majority case where HWIA#default takes only one arhument 2022-12-17 17:08:33 +09:00
Akira Matsuda
c989a2908e
👮 2022-12-17 16:01:37 +09:00
Akira Matsuda
905c720c2c
Cut event.name String in more efficient way 2022-12-17 15:52:18 +09:00
Jonathan Hefner
38a056ce61 Add Message{Encryptors,Verifiers}#transitional
This commit adds a `transitional` attribute to
`ActiveSupport::MessageEncryptors` and `ActiveSupport::MessageVerifiers`.
Setting `transitional = true` will swap the first two rotations when
building a message encryptor / verifier.  For example, with the
following configuration, message verifiers will generate messages using
`serializer: Marshal, url_safe: true`, and will able to verify messages
that were generated using any of the three option sets:

  ```ruby
  verifiers = ActiveSupport::MessageVerifiers.new { ... }
  verifiers.rotate(serializer: JSON, url_safe: true)
  verifiers.rotate(serializer: Marshal, url_safe: true)
  verifiers.rotate(serializer: Marshal, url_safe: false)
  verifiers.transitional = true
  ```

This can be useful when performing a rolling deploy of an application,
wherein servers that have not yet been updated must still be able to
verify messages from updated servers.  In particular, as it can be
applied to the default rotations of `Rails.application.message_verifiers`.
2022-12-16 15:48:10 -06:00
johansenja
0c3c647613 Fix Enumerable#compact_blank example in docs
Only include one non-blank value

Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
2022-12-15 11:48:09 -06:00
Akira Matsuda
bdd090abf6
Unused return value of map 2022-12-15 11:55:03 +09:00
Eileen M. Uchitelle
810343abe1
Merge pull request #46663 from serprex/main
TimeHelpers: include with_usec keyword parameter on travel & freeze too
2022-12-14 10:41:08 -05:00
Philip Dubé
499e9dc737 TimeHelpers: include with_usec keyword parameter on travel & freeze too 2022-12-14 15:20:40 +00:00
Alex Ghiculescu
72c949231b Parallelization test improvements
This fixes some issues I found while working on https://github.com/rails/rails/pull/46718

- Some of the tests in `test_runner_test.rb` generate a new test file, then run it. In some cases, the generated tests were failing. The calling test didn't expect this, but didn't fail despite that. So in this PR I have fixed the generated tests to always pass, and added `allow_failure: false` to enforce this.
- Added a missing test for when `PARALLEL_WORKERS=1`.
- Fixed a typo and removed some unnecessary wording in the docs.
2022-12-13 19:00:53 -06:00
Jean Boussier
cc50791625 AS::Cache#fetch fully skip the read operation when force: true
It makes little sense to emit a `:read` event given we explictly
asked not to read.
2022-12-09 12:35:52 +01:00
Rafael Mendonça França
3f8e31a8c8
Merge pull request #46615 from nickh/nh-fix-transliterate
Return a copy of the source string when transliterating
2022-12-01 14:07:11 -05:00
Jean Boussier
c354e23ee8
Merge pull request #46553 from Shopify/thread-lock
Make AbstractAdapter#lock thread local by default
2022-12-01 16:10:52 +01:00
Nick Hengeveld
5623f7f1a3 Return a copy of the source string when transliterating
Co-authored-by: Adam Hess <hparker@github.com>

Fixes an issue where parameterizing strings was mutating the source, eg:

```ruby
require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  gem "rails", github: "rails/rails", branch: "main"
  gem "sqlite3"
end

require "active_record"
require "minitest/autorun"
require "logger"

ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :posts, force: true do |t|
    t.text :name
    t.text :slug
  end
end

class Post < ActiveRecord::Base
  validate :generate_slug

  def generate_slug
    self.slug = name.parameterize
  end
end

class BugTest < Minitest::Test
  def test_name_gets_corrupted
    post = Post.create!(name: "hi there")

    assert_equal "hi there", post.name # This test fails, "hi-there"
  end
end
```
2022-11-30 16:55:46 +00:00
Hartley McGuire
a07f2ace03
Fix lots of code highlighting issues
The most common is replacing back-ticks with either pluses or tt tags.
There were also a few instances of code blocks not being indented.
2022-11-29 00:51:02 -05:00
Rafael Mendonça França
f6b386d182
Merge pull request #46550 from etiennebarrie/initialize-deprecators-before-config_initializers
Initialize deprecators before config/initializers run
2022-11-28 14:42:12 -05:00
Sean Floyd
8194f8ec88
Improve ActiveSupport::Inflector.transliterate performance
resolves #46569

```ruby

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  gem "rails", github: "rails/rails", branch: "main"
  gem "benchmark-ips"
end

require "active_support"
require "active_support/inflector/transliterate"

module ActiveSupport::Inflector
  def transliterate_fast(string, replacement = "?", locale: nil)
    raise ArgumentError, "Can only transliterate strings. Received #{string.class.name}" unless string.is_a?(String)
    raise ArgumentError, "Cannot transliterate strings with #{string.encoding} encoding" unless ALLOWED_ENCODINGS_FOR_TRANSLITERATE.include?(string.encoding)

    return string if string.ascii_only?

    string = string.dup if string.frozen?
    input_encoding = string.encoding

    # US-ASCII is a subset of UTF-8 so we'll force encoding as UTF-8 if
    # US-ASCII is given. This way we can let tidy_bytes handle the string
    # in the same way as we do for UTF-8
    string.force_encoding(Encoding::UTF_8) if string.encoding == Encoding::US_ASCII

    # GB18030 is Unicode compatible but is not a direct mapping so needs to be
    # transcoded. Using invalid/undef :replace will result in loss of data in
    # the event of invalid characters, but since tidy_bytes will replace
    # invalid/undef with a "?" we're safe to do the same beforehand
    string.encode!(Encoding::UTF_8, invalid: :replace, undef: :replace) if string.encoding == Encoding::GB18030

    transliterated = I18n.transliterate(
      ActiveSupport::Multibyte::Unicode.tidy_bytes(string).unicode_normalize(:nfc),
      replacement: replacement,
      locale: locale
    )

    # Restore the string encoding of the input if it was not UTF-8.
    # Apply invalid/undef :replace as tidy_bytes does
    transliterated.encode!(input_encoding, invalid: :replace, undef: :replace) if input_encoding != transliterated.encoding

    transliterated
  end
end

SCENARIOS = {
  "Empty"                         => "",
  "Single Space"                  => " ",
  "ASCII string"                  => "This is a normal ASCII String.",
  "US ASCII encoded String"       => String.new("This is a normal ASCII String.", encoding: Encoding::US_ASCII),
  "Very Long String"              => "Very Long String :)" * 100,
  "Very Long french String"       => "Very Long Stringé :)" * 100,
  "French string"                 => "Ceci est une chaîne de test pour la méthode de translittération.",
  "UTF-8 encoded Chinese string"  => String.new("這是音譯方法的測試字符串", encoding: Encoding::UTF_8)

}

SCENARIOS.each_pair do |name, value|
  puts
  puts " #{name} ".center(80, "=")
  puts

  Benchmark.ips do |x|
    x.report("transliterate")      { ActiveSupport::Inflector.transliterate(value) }
    x.report("transliterate_fast") { ActiveSupport::Inflector.transliterate_fast(value) }
    x.compare!
  end
end
```

```txt
==================================== Empty =====================================

Warming up --------------------------------------
       transliterate    65.500k i/100ms
  transliterate_fast   687.485k i/100ms
Calculating -------------------------------------
       transliterate    657.632k (± 0.8%) i/s -      3.340M in   5.079936s
  transliterate_fast      6.869M (± 1.6%) i/s -     34.374M in   5.005813s

Comparison:
  transliterate_fast:  6868816.3 i/s
       transliterate:   657631.8 i/s - 10.44x  (± 0.00) slower

================================= Single Space =================================

Warming up --------------------------------------
       transliterate    62.732k i/100ms
  transliterate_fast   678.223k i/100ms
Calculating -------------------------------------
       transliterate    628.475k (± 0.8%) i/s -      3.199M in   5.090978s
  transliterate_fast      6.799M (± 0.2%) i/s -     34.589M in   5.087534s

Comparison:
  transliterate_fast:  6798890.3 i/s
       transliterate:   628475.2 i/s - 10.82x  (± 0.00) slower

================================= ASCII string =================================

Warming up --------------------------------------
       transliterate    32.095k i/100ms
  transliterate_fast   687.396k i/100ms
Calculating -------------------------------------
       transliterate    319.529k (± 0.8%) i/s -      1.605M in   5.022547s
  transliterate_fast      6.879M (± 0.3%) i/s -     35.057M in   5.096224s

Comparison:
  transliterate_fast:  6879113.6 i/s
       transliterate:   319528.9 i/s - 21.53x  (± 0.00) slower

=========================== US ASCII encoded String ============================

Warming up --------------------------------------
       transliterate    33.027k i/100ms
  transliterate_fast   688.354k i/100ms
Calculating -------------------------------------
       transliterate    330.268k (± 0.9%) i/s -      1.651M in   5.000445s
  transliterate_fast      6.861M (± 0.8%) i/s -     34.418M in   5.016963s

Comparison:
  transliterate_fast:  6860726.0 i/s
       transliterate:   330267.8 i/s - 20.77x  (± 0.00) slower

=============================== Very Long String ===============================

Warming up --------------------------------------
       transliterate   985.000  i/100ms
  transliterate_fast   672.674k i/100ms
Calculating -------------------------------------
       transliterate      9.899k (± 0.5%) i/s -     50.235k in   5.074820s
  transliterate_fast      6.729M (± 0.7%) i/s -     34.306M in   5.098807s

Comparison:
  transliterate_fast:  6728668.4 i/s
       transliterate:     9899.2 i/s - 679.72x  (± 0.00) slower

=========================== Very Long french String ============================

Warming up --------------------------------------
       transliterate   671.000  i/100ms
  transliterate_fast   671.000  i/100ms
Calculating -------------------------------------
       transliterate      6.635k (± 1.9%) i/s -     33.550k in   5.058424s
  transliterate_fast      6.622k (± 1.7%) i/s -     33.550k in   5.068289s

Comparison:
       transliterate:     6634.9 i/s
  transliterate_fast:     6621.7 i/s - same-ish: difference falls within error

================================ French string =================================

Warming up --------------------------------------
       transliterate    14.726k i/100ms
  transliterate_fast    14.679k i/100ms
Calculating -------------------------------------
       transliterate    145.933k (± 1.5%) i/s -    736.300k in   5.046537s
  transliterate_fast    146.753k (± 1.2%) i/s -    733.950k in   5.001937s

Comparison:
  transliterate_fast:   146752.8 i/s
       transliterate:   145933.1 i/s - same-ish: difference falls within error

========================= UTF-8 encoded Chinese string =========================

Warming up --------------------------------------
       transliterate    13.905k i/100ms
  transliterate_fast    14.093k i/100ms
Calculating -------------------------------------
       transliterate    141.222k (± 1.9%) i/s -    709.155k in   5.023366s
  transliterate_fast    140.510k (± 1.7%) i/s -    704.650k in   5.016400s

Comparison:
       transliterate:   141221.9 i/s
  transliterate_fast:   140510.4 i/s - same-ish: difference falls within error
```
2022-11-28 08:01:57 -03:00
Étienne Barrié
3d6a7b2faa Initialize deprecators before configuring them
Since engine initializers run later in the process, we need to run this
initializer earlier than the default.

This ensures they're all registered before the environments are loaded.
2022-11-28 10:47:26 +01:00
Jonathan Hefner
ff38e2effc Add Deprecators#disallowed_warnings=
Although disallowed warnings are likely to be deprecator-specific, it
can be useful to set this value once and have it applied to any
deprecators that are added later.  For example, setting the value in an
initializer via `config.active_support.disallowed_deprecation_warnings`
and applying it to any third-party deprecators that are added later in
the boot process.  Also, when using `:all`, it is more convenient to
write `deprecators.disallowed_warnings = :all` instead of
`deprecators.each { |deprecator| deprecator.disallowed_warnings = :all }`.
2022-11-25 12:30:08 -06:00