[ https://issues.apache.org/jira/browse/AVRO-2039?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16692931#comment-16692931 ]
ASF GitHub Bot commented on AVRO-2039: -------------------------------------- Fokko closed pull request #230: AVRO-2039: Ruby encoding performance improvements URL: https://github.com/apache/avro/pull/230 This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/lang/ruby/lib/avro/io.rb b/lang/ruby/lib/avro/io.rb index 26bda973a..958159c79 100644 --- a/lang/ruby/lib/avro/io.rb +++ b/lang/ruby/lib/avro/io.rb @@ -5,9 +5,9 @@ # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -45,7 +45,7 @@ def initialize(reader) def byte! @reader.read(1).unpack('C').first end - + def read_null # null is written as zero byte's nil @@ -159,7 +159,7 @@ def write_null(datum) nil end - # a boolean is written as a single byte + # a boolean is written as a single byte # whose value is either 0 (false) or 1 (true). def write_boolean(datum) on_disk = datum ? 1.chr : 0.chr @@ -504,7 +504,7 @@ def write(datum, encoder) def write_data(writers_schema, logical_datum, encoder) datum = writers_schema.type_adapter.encode(logical_datum) - unless Schema.validate(writers_schema, datum, encoded = true) + unless Schema.validate(writers_schema, datum, { recursive: false, encoded: true }) raise AvroTypeError.new(writers_schema, datum) end @@ -539,6 +539,7 @@ def write_enum(writers_schema, datum, encoder) end def write_array(writers_schema, datum, encoder) + raise AvroTypeError.new(writers_schema, datum) unless datum.is_a?(Array) if datum.size > 0 encoder.write_long(datum.size) datum.each do |item| @@ -549,6 +550,7 @@ def write_array(writers_schema, datum, encoder) end def write_map(writers_schema, datum, encoder) + raise AvroTypeError.new(writers_schema, datum) unless datum.is_a?(Hash) if datum.size > 0 encoder.write_long(datum.size) datum.each do |k,v| @@ -571,6 +573,7 @@ def write_union(writers_schema, datum, encoder) end def write_record(writers_schema, datum, encoder) + raise AvroTypeError.new(writers_schema, datum) unless datum.is_a?(Hash) writers_schema.fields.each do |field| write_data(field.type, datum[field.name], encoder) end diff --git a/lang/ruby/lib/avro/schema.rb b/lang/ruby/lib/avro/schema.rb index 3acd07b7f..c1b150ead 100644 --- a/lang/ruby/lib/avro/schema.rb +++ b/lang/ruby/lib/avro/schema.rb @@ -96,8 +96,8 @@ def self.real_parse(json_obj, names=nil, default_namespace=nil) end # Determine if a ruby datum is an instance of a schema - def self.validate(expected_schema, logical_datum, encoded = false) - SchemaValidator.validate!(expected_schema, logical_datum, encoded) + def self.validate(expected_schema, logical_datum, options = { recursive: true, encoded: false }) + SchemaValidator.validate!(expected_schema, logical_datum, options) true rescue SchemaValidator::ValidationError false diff --git a/lang/ruby/lib/avro/schema_validator.rb b/lang/ruby/lib/avro/schema_validator.rb index 2117e92d4..28022a8c6 100644 --- a/lang/ruby/lib/avro/schema_validator.rb +++ b/lang/ruby/lib/avro/schema_validator.rb @@ -20,7 +20,8 @@ class SchemaValidator PATH_SEPARATOR = '.'.freeze INT_RANGE = Schema::INT_MIN_VALUE..Schema::INT_MAX_VALUE LONG_RANGE = Schema::LONG_MIN_VALUE..Schema::LONG_MAX_VALUE - COMPLEX_TYPES = [:array, :error, :map, :record, :request] + COMPLEX_TYPES = [:array, :error, :map, :record, :request].freeze + BOOLEAN_VALUES = [true, false].freeze class Result attr_reader :errors @@ -62,27 +63,54 @@ def to_s TypeMismatchError = Class.new(ValidationError) class << self - def validate!(expected_schema, logical_datum, encoded = false) + def validate!(expected_schema, logical_datum, options = { recursive: true, encoded: false }) + options ||= {} + options[:recursive] = true unless options.key?(:recursive) + result = Result.new - validate_recursive(expected_schema, logical_datum, ROOT_IDENTIFIER, result, encoded) + if options[:recursive] + validate_recursive(expected_schema, logical_datum, ROOT_IDENTIFIER, result, options) + else + validate_simple(expected_schema, logical_datum, ROOT_IDENTIFIER, result, options) + end fail ValidationError, result if result.failure? result end private - def validate_recursive(expected_schema, logical_datum, path, result, encoded = false) - datum = if encoded - logical_datum - else - expected_schema.type_adapter.encode(logical_datum) rescue nil - end + def validate_recursive(expected_schema, logical_datum, path, result, options = {}) + datum = resolve_datum(expected_schema, logical_datum, options[:encoded]) + + validate_simple(expected_schema, datum, path, result, encoded: true) + + case expected_schema.type_sym + when :array + validate_array(expected_schema, datum, path, result) + when :map + validate_map(expected_schema, datum, path, result) + when :union + validate_union(expected_schema, datum, path, result) + when :record, :error, :request + fail TypeMismatchError unless datum.is_a?(Hash) + expected_schema.fields.each do |field| + deeper_path = deeper_path_for_hash(field.name, path) + validate_recursive(field.type, datum[field.name], deeper_path, result) + end + end + rescue TypeMismatchError + result.add_error(path, "expected type #{expected_schema.type_sym}, got #{actual_value_message(datum)}") + end + + def validate_simple(expected_schema, logical_datum, path, result, options = {}) + datum = resolve_datum(expected_schema, logical_datum, options[:encoded]) + validate_type(expected_schema) case expected_schema.type_sym when :null fail TypeMismatchError unless datum.nil? when :boolean - fail TypeMismatchError unless [true, false].include?(datum) + fail TypeMismatchError unless BOOLEAN_VALUES.include?(datum) when :string, :bytes fail TypeMismatchError unless datum.is_a?(String) when :int @@ -92,36 +120,42 @@ def validate_recursive(expected_schema, logical_datum, path, result, encoded = f fail TypeMismatchError unless datum.is_a?(Integer) result.add_error(path, "out of bound value #{datum}") unless LONG_RANGE.cover?(datum) when :float, :double - fail TypeMismatchError unless [Float, Integer].any?(&datum.method(:is_a?)) + fail TypeMismatchError unless datum.is_a?(Float) || datum.is_a?(Integer) when :fixed if datum.is_a? String - message = "expected fixed with size #{expected_schema.size}, got \"#{datum}\" with size #{datum.size}" - result.add_error(path, message) unless datum.bytesize == expected_schema.size + result.add_error(path, fixed_string_message(expected_schema.size, datum)) unless datum.bytesize == expected_schema.size else result.add_error(path, "expected fixed with size #{expected_schema.size}, got #{actual_value_message(datum)}") end when :enum - message = "expected enum with values #{expected_schema.symbols}, got #{actual_value_message(datum)}" - result.add_error(path, message) unless expected_schema.symbols.include?(datum) - when :array - validate_array(expected_schema, datum, path, result) - when :map - validate_map(expected_schema, datum, path, result) - when :union - validate_union(expected_schema, datum, path, result) - when :record, :error, :request - fail TypeMismatchError unless datum.is_a?(Hash) - expected_schema.fields.each do |field| - deeper_path = deeper_path_for_hash(field.name, path) - validate_recursive(field.type, datum[field.name], deeper_path, result) - end - else - fail "Unexpected schema type #{expected_schema.type_sym} #{expected_schema.inspect}" + result.add_error(path, enum_message(expected_schema.symbols, datum)) unless expected_schema.symbols.include?(datum) end rescue TypeMismatchError result.add_error(path, "expected type #{expected_schema.type_sym}, got #{actual_value_message(datum)}") end + def resolve_datum(expected_schema, logical_datum, encoded) + if encoded + logical_datum + else + expected_schema.type_adapter.encode(logical_datum) rescue nil + end + end + + def validate_type(expected_schema) + unless Avro::Schema::VALID_TYPES_SYM.include?(expected_schema.type_sym) + fail "Unexpected schema type #{expected_schema.type_sym} #{expected_schema.inspect}" + end + end + + def fixed_string_message(size, datum) + "expected fixed with size #{size}, got \"#{datum}\" with size #{datum.size}" + end + + def enum_message(symbols, datum) + "expected enum with values #{symbols}, got #{actual_value_message(datum)}" + end + def validate_array(expected_schema, datum, path, result) fail TypeMismatchError unless datum.is_a?(Array) datum.each_with_index do |d, i| @@ -145,9 +179,10 @@ def validate_union(expected_schema, datum, path, result) validate_recursive(expected_schema.schemas.first, datum, path, result) return end - types_and_results = validate_possible_types(datum, expected_schema, path) - failures, successes = types_and_results.partition { |r| r[:result].failure? } - return if successes.any? + failures = [] + compatible_type = first_compatible_type(datum, expected_schema, path, failures) + return unless compatible_type.nil? + complex_type_failed = failures.detect { |r| COMPLEX_TYPES.include?(r[:type]) } if complex_type_failed complex_type_failed[:result].errors.each { |error| result << error } @@ -157,11 +192,12 @@ def validate_union(expected_schema, datum, path, result) end end - def validate_possible_types(datum, expected_schema, path) - expected_schema.schemas.map do |schema| + def first_compatible_type(datum, expected_schema, path, failures) + expected_schema.schemas.find do |schema| result = Result.new validate_recursive(schema, datum, path, result) - { type: schema.type_sym, result: result } + failures << { type: schema.type_sym, result: result } if result.failure? + !result.failure? end end @@ -169,8 +205,6 @@ def deeper_path_for_hash(sub_key, path) "#{path}#{PATH_SEPARATOR}#{sub_key}".squeeze(PATH_SEPARATOR) end - private - def actual_value_message(value) avro_type = if value.is_a?(Integer) ruby_integer_to_avro_type(value) diff --git a/lang/ruby/test/test_io.rb b/lang/ruby/test/test_io.rb index 70bb4d60c..b518708b0 100644 --- a/lang/ruby/test/test_io.rb +++ b/lang/ruby/test/test_io.rb @@ -158,6 +158,27 @@ def test_fixed check_default(fixed_schema, '"a"', "a") end + def test_record_with_nil + schema = Avro::Schema.parse('{"type":"record", "name":"rec", "fields":[{"type":"int", "name":"i"}]}') + assert_raise(Avro::IO::AvroTypeError) do + write_datum(nil, schema) + end + end + + def test_array_with_nil + schema = Avro::Schema.parse('{"type":"array", "items":"int"}') + assert_raise(Avro::IO::AvroTypeError) do + write_datum(nil, schema) + end + end + + def test_map_with_nil + schema = Avro::Schema.parse('{"type":"map", "values":"long"}') + assert_raise(Avro::IO::AvroTypeError) do + write_datum(nil, schema) + end + end + def test_enum_with_duplicate str = '{"type": "enum", "name": "Test","symbols" : ["AA", "AA"]}' assert_raises(Avro::SchemaParseError) do diff --git a/lang/ruby/test/test_schema_validator.rb b/lang/ruby/test/test_schema_validator.rb index e77569a31..c4759da7b 100644 --- a/lang/ruby/test/test_schema_validator.rb +++ b/lang/ruby/test/test_schema_validator.rb @@ -21,6 +21,10 @@ def validate!(schema, value) Avro::SchemaValidator.validate!(schema, value) end + def validate_simple!(schema, value) + Avro::SchemaValidator.validate!(schema, value, recursive: false) + end + def hash_to_schema(hash) Avro::Schema.parse(hash.to_json) end @@ -36,13 +40,16 @@ def assert_failed_validation(messages) assert_equal(assert_messages.size, result_errors.size) end - def assert_valid_schema(schema, valid, invalid) + def assert_valid_schema(schema, valid, invalid, simple = false) valid.each do |value| assert_nothing_raised { Avro::SchemaValidator.validate!(schema, value) } + assert_nothing_raised { Avro::SchemaValidator.validate!(schema, value, recursive: false) } if simple end invalid.each do |value| assert_raise { Avro::SchemaValidator.validate!(schema, value) } + assert_raise { Avro::SchemaValidator.validate!(schema, value, recursive: false) } if simple + assert_nothing_raised { Avro::SchemaValidator.validate!(schema, value, recursive: false) } unless simple end end @@ -50,10 +57,15 @@ def test_validate_nil schema = hash_to_schema(type: 'null', name: 'name') assert_nothing_raised { validate!(schema, nil) } + assert_nothing_raised { validate_simple!(schema, nil) } assert_failed_validation('at . expected type null, got int with value 1') do validate!(schema, 1) end + + assert_failed_validation('at . expected type null, got int with value 1') do + validate_simple!(schema, 1) + end end def test_validate_boolean @@ -61,52 +73,67 @@ def test_validate_boolean assert_nothing_raised { validate!(schema, true) } assert_nothing_raised { validate!(schema, false) } + assert_nothing_raised { validate_simple!(schema, true) } + assert_nothing_raised { validate_simple!(schema, false) } assert_failed_validation('at . expected type boolean, got int with value 1') do validate!(schema, 1) end + assert_failed_validation('at . expected type boolean, got int with value 1') do + validate_simple!(schema, 1) + end assert_failed_validation('at . expected type boolean, got null') do validate!(schema, nil) end + assert_failed_validation('at . expected type boolean, got null') do + validate_simple!(schema, nil) + end end def test_fixed_size_string schema = hash_to_schema(type: 'fixed', name: 'some', size: 3) assert_nothing_raised { validate!(schema, 'baf') } + assert_nothing_raised { validate_simple!(schema, 'baf') } assert_failed_validation('at . expected fixed with size 3, got "some" with size 4') do validate!(schema, 'some') end + assert_failed_validation('at . expected fixed with size 3, got "some" with size 4') do + validate_simple!(schema, 'some') + end assert_failed_validation('at . expected fixed with size 3, got null') do validate!(schema, nil) end + assert_failed_validation('at . expected fixed with size 3, got null') do + validate_simple!(schema, nil) + end end def test_original_validate_nil schema = hash_to_schema(type: 'null', name: 'name') - assert_valid_schema(schema, [nil], ['something']) + assert_valid_schema(schema, [nil], ['something'], true) end def test_original_validate_boolean schema = hash_to_schema(type: 'boolean', name: 'name') - assert_valid_schema(schema, [true, false], [nil, 1]) + assert_valid_schema(schema, [true, false], [nil, 1], true) end def test_validate_string schema = hash_to_schema(type: 'string', name: 'name') - assert_valid_schema(schema, ['string'], [nil, 1]) + assert_valid_schema(schema, ['string'], [nil, 1], true) end def test_validate_bytes schema = hash_to_schema(type: 'bytes', name: 'name') - assert_valid_schema(schema, ['string'], [nil, 1]) + assert_valid_schema(schema, ['string'], [nil, 1], true) end def test_validate_int @@ -115,41 +142,45 @@ def test_validate_int assert_valid_schema( schema, [Avro::Schema::INT_MIN_VALUE, Avro::Schema::INT_MAX_VALUE, 1], - [Avro::Schema::LONG_MIN_VALUE, Avro::Schema::LONG_MAX_VALUE, 'string'] + [Avro::Schema::LONG_MIN_VALUE, Avro::Schema::LONG_MAX_VALUE, 'string'], + true ) assert_failed_validation('at . out of bound value 9223372036854775807') do validate!(schema, Avro::Schema::LONG_MAX_VALUE) end + assert_failed_validation('at . out of bound value 9223372036854775807') do + validate_simple!(schema, Avro::Schema::LONG_MAX_VALUE) + end end def test_validate_long schema = hash_to_schema(type: 'long', name: 'name') - assert_valid_schema(schema, [Avro::Schema::LONG_MIN_VALUE, Avro::Schema::LONG_MAX_VALUE, 1], [1.1, 'string']) + assert_valid_schema(schema, [Avro::Schema::LONG_MIN_VALUE, Avro::Schema::LONG_MAX_VALUE, 1], [1.1, 'string'], true) end def test_validate_float schema = hash_to_schema(type: 'float', name: 'name') - assert_valid_schema(schema, [1.1, 1, Avro::Schema::LONG_MAX_VALUE], ['string']) + assert_valid_schema(schema, [1.1, 1, Avro::Schema::LONG_MAX_VALUE], ['string'], true) end def test_validate_double schema = hash_to_schema(type: 'double', name: 'name') - assert_valid_schema(schema, [1.1, 1, Avro::Schema::LONG_MAX_VALUE], ['string']) + assert_valid_schema(schema, [1.1, 1, Avro::Schema::LONG_MAX_VALUE], ['string'], true) end def test_validate_fixed schema = hash_to_schema(type: 'fixed', name: 'name', size: 3) - assert_valid_schema(schema, ['abc'], ['ab', 1, 1.1, true]) + assert_valid_schema(schema, ['abc'], ['ab', 1, 1.1, true], true) end def test_validate_original_num schema = hash_to_schema(type: 'enum', name: 'name', symbols: %w(a b)) - assert_valid_schema(schema, ['a', 'b'], ['c']) + assert_valid_schema(schema, ['a', 'b'], ['c'], true) end def test_validate_record @@ -164,22 +195,22 @@ def test_validate_shallow_record ) assert_nothing_raised { validate!(schema, 'sub' => 1) } + assert_nothing_raised { validate_simple!(schema, 'sub' => 1) } assert_failed_validation('at .sub expected type int, got null') do validate!(schema, {}) end + assert_nothing_raised { validate_simple!(schema, {}) } assert_failed_validation('at . expected type record, got float with value 1.2') do validate!(schema, 1.2) end + assert_nothing_raised { validate_simple!(schema, 1.2) } assert_failed_validation('at .sub expected type int, got float with value 1.2') do validate!(schema, 'sub' => 1.2) end - - assert_failed_validation('at .sub expected type int, got null') do - validate!(schema, {}) - end + assert_nothing_raised { validate_simple!(schema, 'sub' => 1.2) } end def test_validate_array @@ -188,18 +219,22 @@ def test_validate_array items: [{ type: 'int', name: 'height' }]) assert_nothing_raised { validate!(schema, []) } + assert_nothing_raised { validate_simple!(schema, []) } assert_failed_validation 'at . expected type array, got null' do validate!(schema, nil) end + assert_nothing_raised { validate_simple!(schema, nil) } assert_failed_validation('at .[0] expected type int, got null') do validate!(schema, [nil]) end + assert_nothing_raised { validate_simple!(schema, [nil]) } assert_failed_validation('at .[3] expected type int, got string with value "so wrong"') do validate!(schema, [1, 3, 9, 'so wrong']) end + assert_nothing_raised { validate_simple!(schema, [1, 3, 9, 'so wrong']) } end def test_validate_enum @@ -208,10 +243,14 @@ def test_validate_enum symbols: %w(one two three)) assert_nothing_raised { validate!(schema, 'one') } + assert_nothing_raised { validate_simple!(schema, 'one') } assert_failed_validation('at . expected enum with values ["one", "two", "three"], got string with value "five"') do validate!(schema, 'five') end + assert_failed_validation('at . expected enum with values ["one", "two", "three"], got string with value "five"') do + validate_simple!(schema, 'five') + end end def test_validate_union_on_primitive_types @@ -226,6 +265,7 @@ def test_validate_union_on_primitive_types assert_failed_validation('at .what_ever expected union of [\'long\', \'string\'], got null') { validate!(schema, 'what_ever' => nil) } + assert_nothing_raised { validate_simple!(schema, 'what_ever' => nil) } end def test_validate_union_of_nil_and_record_inside_array @@ -267,22 +307,27 @@ def test_validate_union_of_nil_and_record_inside_array assert_failed_validation('at .person expected type record, got null') { validate!(schema, 'not at all' => nil) } + assert_nothing_raised { validate_simple!(schema, 'person' => {}) } + assert_nothing_raised { validate!(schema, 'person' => {}) } assert_nothing_raised { validate!(schema, 'person' => { houses: [] }) } assert_nothing_raised { validate!(schema, 'person' => { 'houses' => [{ 'number_of_rooms' => 1 }] }) } + assert_nothing_raised { validate_simple!(schema, 'person' => {}) } + assert_nothing_raised { validate_simple!(schema, 'person' => { houses: [] }) } + assert_nothing_raised { validate_simple!(schema, 'person' => { 'houses' => [{ 'number_of_rooms' => 1 }] }) } + message = 'at .person.houses[1].number_of_rooms expected type long, got string with value "not valid at all"' - assert_failed_validation(message) do - validate!( - schema, - 'person' => { - 'houses' => [ - { 'number_of_rooms' => 2 }, - { 'number_of_rooms' => 'not valid at all' } - ] - } - ) - end + datum = { + 'person' => { + 'houses' => [ + { 'number_of_rooms' => 2 }, + { 'number_of_rooms' => 'not valid at all' } + ] + } + } + assert_failed_validation(message) { validate!(schema, datum) } + assert_nothing_raised { validate_simple!(schema, datum) } end def test_validate_map @@ -293,18 +338,22 @@ def test_validate_map ]) assert_nothing_raised { validate!(schema, 'some' => 1) } + assert_nothing_raised { validate_simple!(schema, 'some' => 1) } assert_failed_validation('at .some expected type int, got string with value "nope"') do validate!(schema, 'some' => 'nope') end + assert_nothing_raised { validate_simple!(schema, 'some' => 'nope')} assert_failed_validation("at . unexpected key type 'Symbol' in map") do validate!(schema, some: 1) end + assert_nothing_raised { validate_simple!(schema, some: 1) } assert_failed_validation('at . expected type map, got null') do validate!(schema, nil) end + assert_nothing_raised { validate_simple!(schema, nil) } end def test_validate_deep_record @@ -336,22 +385,27 @@ def test_validate_deep_record ]) assert_nothing_raised { validate!(schema, 'head' => { 'hair' => { 'color' => 'black' } }) } + assert_nothing_raised { validate_simple!(schema, 'head' => { 'hair' => { 'color' => 'black' } }) } assert_failed_validation('at .head.hair.color expected type string, got null') do validate!(schema, 'head' => { 'hair' => { 'color' => nil } }) end + assert_nothing_raised { validate_simple!(schema, 'head' => { 'hair' => { 'color' => nil } }) } assert_failed_validation('at .head.hair.color expected type string, got null') do validate!(schema, 'head' => { 'hair' => {} }) end + assert_nothing_raised { validate_simple!(schema, 'head' => { 'hair' => {} }) } assert_failed_validation('at .head.hair expected type record, got null') do validate!(schema, 'head' => {}) end + assert_nothing_raised { validate_simple!(schema, 'head' => {}) } assert_failed_validation('at . expected type record, got null') do validate!(schema, nil) end + assert_nothing_raised { validate_simple!(schema, nil) } end def test_validate_deep_record_with_array @@ -377,14 +431,17 @@ def test_validate_deep_record_with_array } ]) assert_nothing_raised { validate!(schema, 'fruits' => [{ 'name' => 'apple', 'weight' => 30.2 }]) } + assert_nothing_raised { validate_simple!(schema, 'fruits' => [{ 'name' => 'apple', 'weight' => 30.2 }]) } assert_failed_validation('at .fruits[0].name expected type string, got null') do validate!(schema, 'fruits' => [{ 'name' => nil, 'weight' => 30.2 }]) end + assert_nothing_raised { validate_simple!(schema, 'fruits' => [{ 'name' => nil, 'weight' => 30.2 }]) } assert_failed_validation('at .fruits expected type array, got int with value 1') do validate!(schema, 'fruits' => 1) end + assert_nothing_raised { validate_simple!(schema, 'fruits' => 1) } end def test_validate_multiple_errors @@ -397,6 +454,7 @@ def test_validate_multiple_errors exception = assert_raise(Avro::SchemaValidator::ValidationError) do validate!(schema, [nil, 'e']) end + assert_nothing_raised { validate_simple!(schema, [nil, 'e']) } assert_equal 2, exception.result.errors.size assert_equal( "at .[0] expected type int, got null\nat .[1] expected type int, got string with value \"e\"", ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org > Ruby encoding performance improvement > ------------------------------------- > > Key: AVRO-2039 > URL: https://issues.apache.org/jira/browse/AVRO-2039 > Project: Apache Avro > Issue Type: Improvement > Components: ruby > Reporter: Tim Perkins > Assignee: Tim Perkins > Priority: Critical > > For a use case with a few levels of nesting and unions in several places > within the schema we saw a 5x improvement in encoding performance with these > changes to encoding using Ruby. > 1. Avoid the exhaustive validation of schemas in a union > 2. Avoid the repeated validation of nested schemas > https://github.com/apache/avro/pull/230 -- This message was sent by Atlassian JIRA (v7.6.3#76005)