panko_serializer 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.clang-format +102 -0
  3. data/.gitignore +12 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +22 -0
  6. data/.travis.yml +8 -0
  7. data/Gemfile +36 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +8 -0
  10. data/Rakefile +62 -0
  11. data/benchmarks/BENCHMARKS.md +48 -0
  12. data/benchmarks/allocs.rb +23 -0
  13. data/benchmarks/app.rb +13 -0
  14. data/benchmarks/benchmarking_support.rb +43 -0
  15. data/benchmarks/bm_active_model_serializers.rb +45 -0
  16. data/benchmarks/bm_controller.rb +81 -0
  17. data/benchmarks/bm_panko_json.rb +60 -0
  18. data/benchmarks/bm_panko_object.rb +69 -0
  19. data/benchmarks/profile.rb +88 -0
  20. data/benchmarks/sanity.rb +67 -0
  21. data/benchmarks/setup.rb +62 -0
  22. data/benchmarks/type_casts/bm_active_record.rb +57 -0
  23. data/benchmarks/type_casts/bm_panko.rb +67 -0
  24. data/benchmarks/type_casts/bm_pg.rb +35 -0
  25. data/benchmarks/type_casts/support.rb +16 -0
  26. data/ext/panko_serializer/attributes_iterator.c +62 -0
  27. data/ext/panko_serializer/attributes_iterator.h +17 -0
  28. data/ext/panko_serializer/extconf.rb +8 -0
  29. data/ext/panko_serializer/panko_serializer.c +189 -0
  30. data/ext/panko_serializer/panko_serializer.h +17 -0
  31. data/ext/panko_serializer/serialization_descriptor.c +166 -0
  32. data/ext/panko_serializer/serialization_descriptor.h +30 -0
  33. data/ext/panko_serializer/time_conversion.c +94 -0
  34. data/ext/panko_serializer/time_conversion.h +6 -0
  35. data/ext/panko_serializer/type_cast.c +271 -0
  36. data/ext/panko_serializer/type_cast.h +74 -0
  37. data/lib/panko/array_serializer.rb +40 -0
  38. data/lib/panko/cache.rb +35 -0
  39. data/lib/panko/serialization_descriptor.rb +119 -0
  40. data/lib/panko/serializer.rb +57 -0
  41. data/lib/panko/version.rb +4 -0
  42. data/lib/panko.rb +8 -0
  43. data/panko_serializer.gemspec +31 -0
  44. metadata +171 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 30e3e534552c9c7592b512b679460e53de9eae33
4
+ data.tar.gz: a0a70502582161816691ba9aaa327ed17695bf8c
5
+ SHA512:
6
+ metadata.gz: 26d0cf119bad48ec684ce49fc8c6413d3a35e976ca135c96d37d7d6e738f19f00f23225195873289bfa5aff3f6059c27bb8bf54fd3f881d75c3e57b4b3da6847
7
+ data.tar.gz: d55cb3c5e156c2f4d64ac67ac9429328d3476944876cdfe4a41ef0b149bd78a636b229061d9648d5a0a9eb3eca79ea68000ab0a6f7ca9d0b472be9163b546903
data/.clang-format ADDED
@@ -0,0 +1,102 @@
1
+ ---
2
+ Language: Cpp
3
+ # BasedOnStyle: Chromium
4
+ AccessModifierOffset: -1
5
+ AlignAfterOpenBracket: Align
6
+ AlignConsecutiveAssignments: false
7
+ AlignConsecutiveDeclarations: false
8
+ AlignEscapedNewlines: Left
9
+ AlignOperands: true
10
+ AlignTrailingComments: true
11
+ AllowAllParametersOfDeclarationOnNextLine: false
12
+ AllowShortBlocksOnASingleLine: false
13
+ AllowShortCaseLabelsOnASingleLine: false
14
+ AllowShortFunctionsOnASingleLine: Inline
15
+ AllowShortIfStatementsOnASingleLine: false
16
+ AllowShortLoopsOnASingleLine: false
17
+ AlwaysBreakAfterDefinitionReturnType: None
18
+ AlwaysBreakAfterReturnType: None
19
+ AlwaysBreakBeforeMultilineStrings: true
20
+ AlwaysBreakTemplateDeclarations: true
21
+ BinPackArguments: true
22
+ BinPackParameters: false
23
+ BraceWrapping:
24
+ AfterClass: false
25
+ AfterControlStatement: false
26
+ AfterEnum: false
27
+ AfterFunction: false
28
+ AfterNamespace: false
29
+ AfterObjCDeclaration: false
30
+ AfterStruct: false
31
+ AfterUnion: false
32
+ BeforeCatch: false
33
+ BeforeElse: false
34
+ IndentBraces: false
35
+ SplitEmptyFunctionBody: true
36
+ BreakBeforeBinaryOperators: None
37
+ BreakBeforeBraces: Attach
38
+ BreakBeforeInheritanceComma: false
39
+ BreakBeforeTernaryOperators: true
40
+ BreakConstructorInitializersBeforeComma: false
41
+ BreakConstructorInitializers: BeforeColon
42
+ BreakAfterJavaFieldAnnotations: false
43
+ BreakStringLiterals: true
44
+ ColumnLimit: 80
45
+ CommentPragmas: '^ IWYU pragma:'
46
+ CompactNamespaces: false
47
+ ConstructorInitializerAllOnOneLineOrOnePerLine: true
48
+ ConstructorInitializerIndentWidth: 4
49
+ ContinuationIndentWidth: 4
50
+ Cpp11BracedListStyle: true
51
+ DerivePointerAlignment: false
52
+ DisableFormat: false
53
+ ExperimentalAutoDetectBinPacking: false
54
+ FixNamespaceComments: true
55
+ ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
56
+ IncludeCategories:
57
+ - Regex: '^<.*\.h>'
58
+ Priority: 1
59
+ - Regex: '^<.*'
60
+ Priority: 2
61
+ - Regex: '.*'
62
+ Priority: 3
63
+ IncludeIsMainRegex: '([-_](test|unittest))?$'
64
+ IndentCaseLabels: true
65
+ IndentWidth: 2
66
+ IndentWrappedFunctionNames: false
67
+ JavaScriptQuotes: Leave
68
+ JavaScriptWrapImports: true
69
+ KeepEmptyLinesAtTheStartOfBlocks: false
70
+ MacroBlockBegin: ''
71
+ MacroBlockEnd: ''
72
+ MaxEmptyLinesToKeep: 1
73
+ NamespaceIndentation: None
74
+ ObjCBlockIndentWidth: 2
75
+ ObjCSpaceAfterProperty: false
76
+ ObjCSpaceBeforeProtocolList: false
77
+ PenaltyBreakAssignment: 2
78
+ PenaltyBreakBeforeFirstCallParameter: 1
79
+ PenaltyBreakComment: 300
80
+ PenaltyBreakFirstLessLess: 120
81
+ PenaltyBreakString: 1000
82
+ PenaltyExcessCharacter: 1000000
83
+ PenaltyReturnTypeOnItsOwnLine: 200
84
+ PointerAlignment: Left
85
+ ReflowComments: true
86
+ SortIncludes: true
87
+ SpaceAfterCStyleCast: false
88
+ SpaceAfterTemplateKeyword: true
89
+ SpaceBeforeAssignmentOperators: true
90
+ SpaceBeforeParens: ControlStatements
91
+ SpaceInEmptyParentheses: false
92
+ SpacesBeforeTrailingComments: 2
93
+ SpacesInAngles: false
94
+ SpacesInContainerLiterals: true
95
+ SpacesInCStyleCastParentheses: false
96
+ SpacesInParentheses: false
97
+ SpacesInSquareBrackets: false
98
+ Standard: Auto
99
+ TabWidth: 8
100
+ UseTab: Never
101
+ ...
102
+
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,22 @@
1
+ AllCops:
2
+ DisabledByDefault: true
3
+ TargetRubyVersion: 2.4.1
4
+ DisplayCopNames: true
5
+ StyleGuideCopsOnly: false
6
+
7
+ Metrics/LineLength:
8
+ Max: 120
9
+
10
+ Style/StringLiterals:
11
+ EnforcedStyle: double_quotes
12
+
13
+ Style/FrozenStringLiteralComment:
14
+ Enabled: true
15
+ EnforcedStyle: always
16
+
17
+ Layout/TrailingBlankLines:
18
+ Enabled: true
19
+
20
+ Layout/TrailingWhitespace:
21
+ Enabled: true
22
+
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ sudo: false
2
+ cache: bundler
3
+ language: ruby
4
+ rvm:
5
+ - 2.4.1
6
+ - ruby-head
7
+ before_install: gem install bundler
8
+ after_success: bundle exec rake benchmarks
data/Gemfile ADDED
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+ source "https://rubygems.org"
3
+
4
+ gemspec
5
+
6
+ version = "4.2"
7
+ gem_version = "~> #{version}.9"
8
+
9
+ gem "rails", gem_version
10
+ gem "railties", gem_version
11
+ gem "activesupport", gem_version
12
+ gem "activemodel", gem_version
13
+ gem "actionpack", gem_version
14
+ gem "activerecord", gem_version, group: :test
15
+
16
+ group :benchmarks do
17
+ gem "sqlite3"
18
+ gem "pg"
19
+
20
+ gem "memory_profiler"
21
+ gem "ruby-prof"
22
+ gem "ruby-prof-flamegraph"
23
+
24
+ gem "benchmark-ips"
25
+ gem "active_model_serializers", "0.9.7"
26
+
27
+ gem "terminal-table"
28
+ end
29
+
30
+ group :test do
31
+ gem "faker"
32
+ end
33
+
34
+ group :development do
35
+ gem "byebug"
36
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Yosi Attias
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,8 @@
1
+ # Panko
2
+
3
+ [![Build Status](https://travis-ci.org/yosiat/panko.svg?branch=master)](https://travis-ci.org/yosiat/panko)
4
+
5
+
6
+ ## License
7
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
8
+
data/Rakefile ADDED
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+ require "bundler/gem_tasks"
3
+ require "rspec/core/rake_task"
4
+ require "json"
5
+ require "terminal-table"
6
+ require "rake/extensiontask"
7
+
8
+ gem = Gem::Specification.load( File.dirname(__FILE__) + "/panko_serializer.gemspec" )
9
+
10
+
11
+ Rake::ExtensionTask.new("panko_serializer", gem) do |ext|
12
+ ext.lib_dir = "lib/panko"
13
+ end
14
+
15
+ Gem::PackageTask.new(gem) do |pkg|
16
+ pkg.need_zip = pkg.need_tar = false
17
+ end
18
+
19
+ RSpec::Core::RakeTask.new(:spec)
20
+ Rake::Task[:spec].prerequisites << :compile
21
+
22
+ task default: :spec
23
+
24
+
25
+ def run_benchmarks(files, items_count: 14_000)
26
+ headings = ["Benchmark", "ip/s", "allocs/retained"]
27
+ files.each do |benchmark_file|
28
+ output = `ITEMS_COUNT=#{items_count} RAILS_ENV=production ruby #{benchmark_file}`
29
+
30
+ rows = output.each_line.map do |line|
31
+ result = JSON.parse(line)
32
+ result.values
33
+ end
34
+
35
+ puts "\n\n"
36
+ title = File.basename(benchmark_file, ".rb")
37
+ table = Terminal::Table.new title: title, headings: headings, rows: rows
38
+ puts table
39
+ end
40
+ end
41
+
42
+ desc "Run all benchmarks"
43
+ task :benchmarks do
44
+ run_benchmarks Dir[File.join(__dir__, "benchmarks", "**", "bm_*")]
45
+ end
46
+
47
+ desc "Type Casts - Benchmarks"
48
+ task :bm_type_casts do
49
+ run_benchmarks Dir[File.join(__dir__, "benchmarks", "type_casts", "bm_*")]
50
+ end
51
+
52
+ desc "Sanity Benchmarks"
53
+ task :sanity do
54
+ puts Time.now.strftime("%d/%m %H:%M:%S")
55
+ puts "=========================="
56
+
57
+ run_benchmarks [
58
+ File.join(__dir__, "benchmarks", "sanity.rb")
59
+ ], items_count: 2300
60
+
61
+ puts "\n\n"
62
+ end
@@ -0,0 +1,48 @@
1
+ ## Initial state
2
+ ```
3
+ Native_Posts_2300 57 ip/s 13802 allocs/op
4
+ Native_Posts_50 2956 ip/s 302 allocs/op
5
+
6
+ AMS_Simple_Posts_2300 21 ip/s 94309 allocs/op
7
+ AMS_Simple_Posts_50 1008 ip/s 2059 allocs/op
8
+ AMS_HasOne_Posts_2300 9 ip/s 147209 allocs/op
9
+ AMS_HasOne_Posts_50 451 ip/s 3209 allocs/op
10
+
11
+ Panko_HasOne_Posts_2300 164 ip/s 2372 allocs/op
12
+ Panko_HasOne_Posts_50 6118 ip/s 122 allocs/op
13
+ Panko_Reused_HasOne_Posts_2300 178 ip/s 2303 allocs/op
14
+ Panko_Reused_HasOne_Posts_50 8203 ip/s 53 allocs/op
15
+
16
+ Panko_Simple_Posts_2300 150 ip/s 2372 allocs/op
17
+ Panko_Simple_Posts_50 5639 ip/s 122 allocs/op
18
+ Panko_Reused_Simple_Posts_2300 180 ip/s 2303 allocs/op
19
+ Panko_Reused_Simple_Posts_50 8388 ip/s 53 allocs/op
20
+ ```
21
+
22
+ ## Refactorings, method call support, combining
23
+
24
+ ### class eval
25
+ ```
26
+ Panko_HasOne_Posts_2300 64 ip/s 9477 allocs/op
27
+ Panko_HasOne_Posts_50 2397 ip/s 477 allocs/op
28
+ Panko_Reused_HasOne_Posts_2300 70 ip/s 9423 allocs/op
29
+ Panko_Reused_HasOne_Posts_50 2596 ip/s 423 allocs/op
30
+
31
+ Panko_Simple_Posts_2300 191 ip/s 2472 allocs/op
32
+ Panko_Simple_Posts_50 5128 ip/s 222 allocs/op
33
+ Panko_Reused_Simple_Posts_2300 180 ip/s 2418 allocs/op
34
+ Panko_Reused_Simple_Posts_50 5534 ip/s 168 allocs/op
35
+ ```
36
+
37
+ ### instance eval
38
+ ```
39
+ Panko_HasOne_Posts_2300 60 ip/s 9473 allocs/op
40
+ Panko_HasOne_Posts_50 2399 ip/s 473 allocs/op
41
+ Panko_Reused_HasOne_Posts_2300 66 ip/s 9419 allocs/op
42
+ Panko_Reused_HasOne_Posts_50 2582 ip/s 419 allocs/op
43
+
44
+ Panko_Simple_Posts_2300 195 ip/s 2470 allocs/op
45
+ Panko_Simple_Posts_50 4838 ip/s 220 allocs/op
46
+ Panko_Reused_Simple_Posts_2300 196 ip/s 2416 allocs/op
47
+ Panko_Reused_Simple_Posts_50 6241 ip/s 166 allocs/op
48
+ ```
@@ -0,0 +1,23 @@
1
+
2
+ # frozen_string_literal: true
3
+ require_relative "./benchmarking_support"
4
+ require_relative "./app"
5
+ require_relative "./setup"
6
+
7
+ require "memory_profiler"
8
+
9
+ class PostFastSerializer < Panko::Serializer
10
+ attributes :id, :body, :title, :author_id
11
+ end
12
+
13
+ def count_allocs(&block)
14
+ memory_report = MemoryProfiler.report(&block)
15
+ puts memory_report.pretty_print
16
+ end
17
+
18
+ posts = Post.all.to_a
19
+ merged_options = {}.merge(each_serializer: PostFastSerializer)
20
+ posts_array_serializer = Panko::ArraySerializer.new([], merged_options)
21
+
22
+ # prints out 18402
23
+ count_allocs { posts_array_serializer.serialize_to_json posts }
data/benchmarks/app.rb ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+ require "bundler/setup"
3
+
4
+
5
+ require "rails"
6
+ require "active_model"
7
+ require "active_support"
8
+ require "active_support/json"
9
+ require "action_controller"
10
+ require "action_controller/railtie"
11
+
12
+ require "active_model_serializers"
13
+ require "panko"
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+ require "benchmark/ips"
3
+ require "json"
4
+ require "memory_profiler"
5
+
6
+ module Benchmark
7
+ module ActiveModelSerializers
8
+ def data
9
+ posts = Post.all.includes(:author).to_a
10
+ posts_50 = posts.first(50).to_a
11
+ { all: posts, small: posts_50 }
12
+ end
13
+
14
+ def ams(label = nil, time: 10, disable_gc: true, warmup: 3, &block)
15
+ fail ArgumentError.new, "block should be passed" unless block_given?
16
+
17
+ GC.start
18
+
19
+ if disable_gc
20
+ GC.disable
21
+ else
22
+ GC.enable
23
+ end
24
+
25
+ memory_report = MemoryProfiler.report(&block)
26
+
27
+ report = Benchmark.ips(time, warmup, true) do |x|
28
+ x.report(label) { yield }
29
+ end
30
+
31
+ results = {
32
+ label: label,
33
+ ips: ActiveSupport::NumberHelper.number_to_delimited(report.entries.first.ips.round(2)),
34
+ allocs: "#{memory_report.total_allocated}/#{memory_report.total_retained}"
35
+ }.to_json
36
+
37
+ puts results
38
+
39
+ end
40
+ end
41
+
42
+ extend Benchmark::ActiveModelSerializers
43
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+ require_relative "./benchmarking_support"
3
+ require_relative "./app"
4
+ require_relative "./setup"
5
+
6
+ class AmsAuthorFastSerializer < ActiveModel::Serializer
7
+ attributes :id, :name
8
+ end
9
+
10
+ class AmsPostFastSerializer < ActiveModel::Serializer
11
+ attributes :id, :body, :title, :author_id
12
+ end
13
+
14
+ class AmsPostWithHasOneFastSerializer < ActiveModel::Serializer
15
+ attributes :id, :body, :title, :author_id
16
+
17
+ has_one :author, serializer: AmsAuthorFastSerializer
18
+ end
19
+
20
+ def benchmark_ams(prefix, serializer, options = {})
21
+ merged_options = options.merge(each_serializer: serializer)
22
+
23
+ data = Benchmark.data
24
+ posts = data[:all]
25
+ posts_50 = data[:small]
26
+
27
+
28
+ Benchmark.ams("AMS_#{prefix}_Posts_#{posts.count}") do
29
+ ActiveModel::ArraySerializer.new(posts, merged_options).serializable_object
30
+ end
31
+
32
+ data = Benchmark.data
33
+ posts = data[:all]
34
+ posts_50 = data[:small]
35
+
36
+ Benchmark.ams("AMS_#{prefix}_Posts_50") do
37
+ ActiveModel::ArraySerializer.new(posts_50, merged_options).serializable_object
38
+ end
39
+ end
40
+
41
+
42
+ benchmark_ams "HasOne", AmsPostWithHasOneFastSerializer
43
+ benchmark_ams "Simple", AmsPostFastSerializer
44
+ benchmark_ams "Except", AmsPostWithHasOneFastSerializer, except: [:title]
45
+ benchmark_ams "Include", AmsPostWithHasOneFastSerializer, include: [:id, :body, :author_id, :author]
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+ require_relative "./benchmarking_support"
3
+ require_relative "./app"
4
+ require_relative "./setup"
5
+
6
+ class NullLogger < Logger
7
+ def initialize(*args)
8
+ end
9
+
10
+ def add(*args, &block)
11
+ end
12
+ end
13
+
14
+ class BenchmarkApp < Rails::Application
15
+ routes.append do
16
+ get "/simple" => "main#simple"
17
+ get "/text" => "main#text"
18
+
19
+ get "/serialize_to_string" => "main#serialize_to_string"
20
+ end
21
+
22
+ config.secret_token = "s"*30
23
+ config.secret_key_base = "foo"
24
+ config.consider_all_requests_local = false
25
+
26
+ # simulate production
27
+ config.cache_classes = true
28
+ config.eager_load = true
29
+ config.action_controller.perform_caching = true
30
+
31
+ # otherwise deadlock occured
32
+ config.middleware.delete "Rack::Lock"
33
+
34
+ # to disable log files
35
+ config.logger = NullLogger.new
36
+ config.active_support.deprecation = :log
37
+ end
38
+
39
+ BenchmarkApp.initialize!
40
+
41
+ class AuthorFastSerializer < Panko::Serializer
42
+ attributes :id, :name
43
+ end
44
+
45
+ class PostWithHasOneFastSerializer < Panko::Serializer
46
+ attributes :id, :body, :title, :author_id
47
+
48
+ has_one :author, serializer: AuthorFastSerializer
49
+ end
50
+
51
+ class MainController < ActionController::Base
52
+ def text
53
+ render text: '{"ok":true}'.freeze, content_type: "application/json".freeze
54
+ end
55
+
56
+ def simple
57
+ render json: { ok: true }
58
+ end
59
+
60
+ def serialize_to_string
61
+ data = Benchmark.data[:all]
62
+ render text: Panko::ArraySerializer.new(data, each_serializer: PostWithHasOneFastSerializer).to_json, content_type: "application/json".freeze
63
+ end
64
+ end
65
+
66
+ class RouteNotFoundError < StandardError;end
67
+
68
+
69
+ def request(method, path)
70
+ response = Rack::MockRequest.new(BenchmarkApp).send(method, path)
71
+ if response.status.in?([404, 500])
72
+ raise RouteNotFoundError.new, 'not found #{method.to_s.upcase} #{path}'
73
+ end
74
+ response
75
+ end
76
+
77
+
78
+ Benchmark.ams("text") { request(:get, "/text") }
79
+ Benchmark.ams("simple") { request(:get, "/simple") }
80
+
81
+ Benchmark.ams("serialize_to_string") { request(:get, "/serialize_to_string") }
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+ require_relative "./benchmarking_support"
3
+ require_relative "./app"
4
+ require_relative "./setup"
5
+
6
+ class AuthorFastSerializer < Panko::Serializer
7
+ attributes :id, :name
8
+ end
9
+
10
+
11
+ class PostFastSerializer < Panko::Serializer
12
+ attributes :id, :body, :title, :author_id
13
+ end
14
+
15
+ class PostFastWithMethodCallSerializer < Panko::Serializer
16
+ attributes :id, :body, :title, :author_id, :method_call
17
+
18
+ def method_call
19
+ object.id * 2
20
+ end
21
+ end
22
+
23
+ class PostWithHasOneFastSerializer < Panko::Serializer
24
+ attributes :id, :body, :title, :author_id
25
+
26
+ has_one :author, serializer: AuthorFastSerializer
27
+ end
28
+
29
+ class AuthorWithHasManyFastSerializer < Panko::Serializer
30
+ attributes :id, :name
31
+
32
+ has_many :posts, serializer: PostFastSerializer
33
+ end
34
+
35
+
36
+ def benchmark(prefix, serializer, options = {})
37
+ data = Benchmark.data
38
+ posts = data[:all]
39
+ posts_50 = data[:small]
40
+
41
+ merged_options = options.merge(each_serializer: serializer)
42
+
43
+ Benchmark.ams("Panko_#{prefix}_Posts_#{posts.count}") do
44
+ Panko::ArraySerializer.new(posts, merged_options).to_json
45
+ end
46
+
47
+ data = Benchmark.data
48
+ posts = data[:all]
49
+ posts_50 = data[:small]
50
+
51
+ Benchmark.ams("Panko_#{prefix}_Posts_50") do
52
+ Panko::ArraySerializer.new(posts_50, merged_options).to_json
53
+ end
54
+ end
55
+
56
+ benchmark "HasOne", PostWithHasOneFastSerializer
57
+ benchmark "Simple", PostFastSerializer
58
+ benchmark "SimpleWithMethodCall", PostFastWithMethodCallSerializer
59
+ benchmark "Except", PostWithHasOneFastSerializer, except: [:title]
60
+ benchmark "Include", PostWithHasOneFastSerializer, include: [:id, :body, :author_id, :author]
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+ require_relative "./benchmarking_support"
3
+ require_relative "./app"
4
+ require_relative "./setup"
5
+
6
+ class AuthorFastSerializer < Panko::Serializer
7
+ attributes :id, :name
8
+ end
9
+
10
+
11
+ class PostFastSerializer < Panko::Serializer
12
+ attributes :id, :body, :title, :author_id
13
+ end
14
+
15
+ class PostWithHasOneFastSerializer < Panko::Serializer
16
+ attributes :id, :body, :title, :author_id
17
+
18
+ has_one :author, serializer: AuthorFastSerializer
19
+ end
20
+
21
+ class AuthorWithHasManyFastSerializer < Panko::Serializer
22
+ attributes :id, :name
23
+
24
+ has_many :posts, serializer: PostFastSerializer
25
+ end
26
+
27
+
28
+ def benchmark(prefix, serializer, options = {})
29
+ data = Benchmark.data
30
+ posts = data[:all]
31
+ posts_50 = data[:small]
32
+
33
+ merged_options = options.merge(each_serializer: serializer)
34
+
35
+ Benchmark.ams("Panko_#{prefix}_Posts_#{posts.count}") do
36
+ Panko::ArraySerializer.new(posts, merged_options).to_a
37
+ end
38
+
39
+ data = Benchmark.data
40
+ posts = data[:all]
41
+ posts_50 = data[:small]
42
+
43
+ Benchmark.ams("Panko_#{prefix}_Posts_50") do
44
+ Panko::ArraySerializer.new(posts_50, merged_options).to_a
45
+ end
46
+
47
+ posts_array_serializer = Panko::ArraySerializer.new([], merged_options)
48
+
49
+ data = Benchmark.data
50
+ posts = data[:all]
51
+ posts_50 = data[:small]
52
+
53
+ Benchmark.ams("Panko_Reused_#{prefix}_Posts_#{posts.count}") do
54
+ posts_array_serializer.serialize posts
55
+ end
56
+
57
+ data = Benchmark.data
58
+ posts = data[:all]
59
+ posts_50 = data[:small]
60
+
61
+ Benchmark.ams("Panko_Reused_#{prefix}_Posts_50") do
62
+ posts_array_serializer.serialize posts_50
63
+ end
64
+ end
65
+
66
+ benchmark "HasOne", PostWithHasOneFastSerializer
67
+ benchmark "Simple", PostFastSerializer
68
+ benchmark "Except", PostWithHasOneFastSerializer, except: [:title]
69
+ benchmark "Include", PostWithHasOneFastSerializer, include: [:id, :body, :author_id, :author]