Is there an easy way to speed up the json rendering of 20,000+ dry-struct objects in rails?


#1

I’m rendering 20,000 + dry-struct objects in JSON using Rails controller. I takes about 7 seconds on Heroku to render the JSON for roughly 22 thousand dry-struct objects.
If you know of a quicker way to generate the JSON then I’d be interested. Thanks!

Rails controller:
render json: {
                samples: sample_list.samples,
                sample_columns: sample_list.sample_columns,
                tests: sample_list.tests.index_by(&:test_id),
    }
class Limit < Dry::Struct
      attribute :type, Types::Strict::String.enum("pass_fail", "warning")
      attribute :formatted, Types::Strict::String
    end

    class LimitType < Dry::Struct
      # type can be MRL or Client Spec
      attribute :type_id, Types::Strict::Integer
      attribute :type, Types::Strict::String
      attribute :limits, Types::Array.of(::SampleTesting::ViewBuilders::Limit)

      def mrl?
        type_id == ::SampleLimits::SampleLimit::MrlLimitType
      end

      def client_spec?
        type_id == ::SampleLimits::SampleLimit::ClientSpecificationType
      end
    end

    class AResultCaveat < Dry::Struct
      attribute :id, Types::Strict::Integer
      attribute :caveat_id, Types::Strict::Integer
      attribute :text, Types::Strict::String
    end

    class Result < Dry::Struct
      transform_keys(&:to_sym)
      attribute :id, Types::Strict::Integer
      attribute :formatted_lod, Types::Strict::String
      attribute :formatted_result, Types::Strict::String
      attribute :reviewed, Types::Bool
      attribute :failed, Types::Bool
      attribute :warning, Types::Bool
      attribute :caveats, Types::Array.of(AResultCaveat).default([])
    end

    class SampleTest < Dry::Struct
      attribute :id, Types::Strict::Integer
      attribute :sample_id, Types::Strict::Integer
      attribute :test_id, Types::Strict::Integer
      attribute :results, Types::Array.of(Result)
      attribute :limit_types, Types::Array.of(LimitType).default([])
    end

    class SampleWithResults < Dry::Struct
      attribute :sample, LimsSampleReporting::ViewBuilders::Sample
      attribute :sample_tests, Types::Array.of(SampleTest)
    end

    class SampleList < Dry::Struct
      transform_keys(&:to_sym)
      attribute :samples, Types::Array.of(SampleWithResults)
      attribute :tests, Types::Array.of(Testing::Domain::Test)
      attribute :sample_columns, Types::Array.default([])
    end

#2

@i2chris Have you run a profiler over this? May be enlightening to see where the hotspots are.


#3

I will try it again. The last time I tried it it crashed before it rendered the flamegraph.


#4

@i2chris I guess you probably want to reduce the number of records when profiling :slight_smile:


#5

Good plan :+1: