Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use rb_enc_get() to retrieve encoding type #685

Merged
merged 1 commit into from Aug 8, 2021

Conversation

Watson1978
Copy link
Collaborator

To reduce overhead, this patch use rb_enc_get() instead.

before after result
Oj.dump 1.319M 1.336M -
Oj.dump (compat) 948.393k 1.125M 1.19x
Oj.dump (rails) 815.509k 943.996k 1.16x

Environment

  • MacBook Air (M1, 2020)
  • macOS 12.0 beta 4
  • Apple M1
  • Ruby 3.0.2

Before

Warming up --------------------------------------
             Oj.dump   131.400k i/100ms
    Oj.dump (compat)    94.239k i/100ms
     Oj.dump (rails)    79.788k i/100ms
Calculating -------------------------------------
             Oj.dump      1.319M (± 0.7%) i/s -      6.701M in   5.080504s
    Oj.dump (compat)    948.393k (± 0.9%) i/s -      4.806M in   5.068098s
     Oj.dump (rails)    815.509k (± 0.8%) i/s -      4.149M in   5.087955s

After

Warming up --------------------------------------
             Oj.dump   133.596k i/100ms
    Oj.dump (compat)   113.563k i/100ms
     Oj.dump (rails)    95.233k i/100ms
Calculating -------------------------------------
             Oj.dump      1.336M (± 1.0%) i/s -      6.680M in   5.000748s
    Oj.dump (compat)      1.125M (± 0.9%) i/s -      5.678M in   5.046279s
     Oj.dump (rails)    943.996k (± 0.8%) i/s -      4.762M in   5.044464s

Test code

require 'benchmark/ips'
require 'oj'

json =<<-EOF
{
  "$id": "https://example.com/person.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Person",
  "type": "object",
  "properties": {
    "firstName": {
      "type": "string",
      "description": "The person's first name."
    },
    "lastName": {
      "type": "string",
      "description": "The person's last name."
    },
    "age": {
      "description": "Age in years which must be equal to or greater than zero.",
      "type": "integer",
      "minimum": 0
    }
  }
}
EOF

Benchmark.ips do |x|
  data = Oj.load(json)
  x.report('Oj.dump') { Oj.dump(data) }
  x.report('Oj.dump (compat)') { Oj.dump(data, mode: :compat) }
  x.report('Oj.dump (rails)') { Oj.dump(data, mode: :rails) }
end

@Watson1978 Watson1978 marked this pull request as draft August 8, 2021 17:41
@Watson1978
Copy link
Collaborator Author

I found the same code in another place.

oj/ext/oj/parse.c

Lines 966 to 971 in 4fdd25d

static void oj_pi_set_input_str(ParseInfo pi, volatile VALUE *inputp) {
rb_encoding *enc = rb_to_encoding(rb_obj_encoding(*inputp));
if (rb_utf8_encoding() != enc) {
*inputp = rb_str_conv_enc(*inputp, enc, rb_utf8_encoding());
}

To reduce overhead, this patch use `rb_enc_get()` instead.

−               | before   | after    | result
--               | --       | --       | --
Oj.dump          | 1.319M   | 1.336M   | -
Oj.dump (compat) | 948.393k | 1.125M   | 1.19x
Oj.dump (rails)  | 815.509k | 943.996k | 1.16x

### Environment
- MacBook Air (M1, 2020)
- macOS 12.0 beta 4
- Apple M1
- Ruby 3.0.2

### Before
```
Warming up --------------------------------------
             Oj.dump   131.400k i/100ms
    Oj.dump (compat)    94.239k i/100ms
     Oj.dump (rails)    79.788k i/100ms
Calculating -------------------------------------
             Oj.dump      1.319M (± 0.7%) i/s -      6.701M in   5.080504s
    Oj.dump (compat)    948.393k (± 0.9%) i/s -      4.806M in   5.068098s
     Oj.dump (rails)    815.509k (± 0.8%) i/s -      4.149M in   5.087955s
```

### After
```
Warming up --------------------------------------
             Oj.dump   133.596k i/100ms
    Oj.dump (compat)   113.563k i/100ms
     Oj.dump (rails)    95.233k i/100ms
Calculating -------------------------------------
             Oj.dump      1.336M (± 1.0%) i/s -      6.680M in   5.000748s
    Oj.dump (compat)      1.125M (± 0.9%) i/s -      5.678M in   5.046279s
     Oj.dump (rails)    943.996k (± 0.8%) i/s -      4.762M in   5.044464s
```

### Test code
```ruby
require 'benchmark/ips'
require 'oj'

json =<<-EOF
{
  "$id": "https://example.com/person.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Person",
  "type": "object",
  "properties": {
    "firstName": {
      "type": "string",
      "description": "The person's first name."
    },
    "lastName": {
      "type": "string",
      "description": "The person's last name."
    },
    "age": {
      "description": "Age in years which must be equal to or greater than zero.",
      "type": "integer",
      "minimum": 0
    }
  }
}
EOF

Benchmark.ips do |x|
  data = Oj.load(json)
  x.report('Oj.dump') { Oj.dump(data) }
  x.report('Oj.dump (compat)') { Oj.dump(data, mode: :compat) }
  x.report('Oj.dump (rails)') { Oj.dump(data, mode: :rails) }
end
```
@Watson1978
Copy link
Collaborator Author

OK, I updated

@Watson1978 Watson1978 marked this pull request as ready for review August 8, 2021 17:46
@ohler55 ohler55 merged commit 1a57032 into ohler55:develop Aug 8, 2021
@Watson1978 Watson1978 deleted the rb_enc_get branch August 9, 2021 05:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants