Skip to content

Hashify / transform_values is unnecessarily being called for nested Dry::Structs #200

@rpeng

Description

@rpeng

value.to_h.transform_values { self[_1] }

If a value is a Dry::Struct, Hashify.[] is already the default implementation of its to_h method. Doing it again in transform_values will be double calling the hashify method, leading to inefficient serialization.

A simple fix here is to just remove the transform_values in the is_a?(Struct) branch - can expect a huge speed up for nested structs.

Found this on 1.6.0 but I believe the same issue is on the main branch from inspecting the implementation

Example:

class Foo < Dry::Struct
  attribute :value, Types::Coercible::String
end

class Bar < Dry::Struct
  attribute :foo, Foo
end

class Baz < Dry::Struct
  attribute :bar, Bar
end

baz = Baz.new(
  bar: {
    foo: {
      value: "hello"
    }
  }
)

baz.to_h # <- "hello" is hashified 3 times!

patched it with some logging output

>> baz.to_h
hashify: #<Bar:0x000000034f66cc70>
hashify: #<Foo:0x000000034f66cd10>
hashify: hello
hashify: hello
hashify: {:value=>"hello"}
hashify: hello

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions