panko_serializer 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 191ab315beed684a1a584eccdcfb500521e5f3b5
4
- data.tar.gz: bdc4bf8c0bdc1e66b09a0221d640ec033b21463c
3
+ metadata.gz: ae00bf37cb1dcce9c00df00c32e4f23bdba6081c
4
+ data.tar.gz: '08e3f85bd87fe2a6c94b4210d53c605c5f5c2f53'
5
5
  SHA512:
6
- metadata.gz: 1075d2458fc18945ece197e3c1b45ed19d7c37cfcad48beed72ee38d0b147b1a338b756ddce9a740d24681192a3a7159953daee5816d182678921d5c818b72ca
7
- data.tar.gz: 278b97815ce09041391744fd01c385e92b0b8bcc54edeecc1250a7f9cc459f19fe5df0d43d77e955e5b6d717677fd81ee67baaa2c5dc87da4b68551da28b921e
6
+ metadata.gz: 158ff5e032d418ae77b9758e9b84429029738c8cc09f40b3ac8d01c29490a1824e9785df97b066fd0bec83f9b2e17728a29680cf90966e0f3908d954e60990e7
7
+ data.tar.gz: 25d8c763c866c2987ad320a72c3a1d9ec93f10a82f6d909d1fe549479262211752c8e79bf70eb2626fba39554482262663b5b5c6c435ae5f2cbe7860dfc63a28
@@ -4,14 +4,14 @@ require "json"
4
4
  require "memory_profiler"
5
5
 
6
6
  module Benchmark
7
- module ActiveModelSerializers
7
+ module Runner
8
8
  def data
9
9
  posts = Post.all.includes(:author).to_a
10
10
  posts_50 = posts.first(50).to_a
11
11
  { all: posts, small: posts_50 }
12
12
  end
13
13
 
14
- def ams(label = nil, time: 10, disable_gc: true, warmup: 3, &block)
14
+ def run(label = nil, time: 10, disable_gc: true, warmup: 3, &block)
15
15
  fail ArgumentError.new, "block should be passed" unless block_given?
16
16
 
17
17
  GC.start
@@ -39,5 +39,5 @@ module Benchmark
39
39
  end
40
40
  end
41
41
 
42
- extend Benchmark::ActiveModelSerializers
42
+ extend Benchmark::Runner
43
43
  end
@@ -25,7 +25,7 @@ def benchmark_ams(prefix, serializer, options = {})
25
25
  posts_50 = data[:small]
26
26
 
27
27
 
28
- Benchmark.ams("AMS_#{prefix}_Posts_#{posts.count}") do
28
+ Benchmark.run("AMS_#{prefix}_Posts_#{posts.count}") do
29
29
  ActiveModel::ArraySerializer.new(posts, merged_options).serializable_object
30
30
  end
31
31
 
@@ -33,7 +33,7 @@ def benchmark_ams(prefix, serializer, options = {})
33
33
  posts = data[:all]
34
34
  posts_50 = data[:small]
35
35
 
36
- Benchmark.ams("AMS_#{prefix}_Posts_50") do
36
+ Benchmark.run("AMS_#{prefix}_Posts_50") do
37
37
  ActiveModel::ArraySerializer.new(posts_50, merged_options).serializable_object
38
38
  end
39
39
  end
@@ -75,7 +75,7 @@ def request(method, path)
75
75
  end
76
76
 
77
77
 
78
- Benchmark.ams("text") { request(:get, "/text") }
79
- Benchmark.ams("simple") { request(:get, "/simple") }
78
+ Benchmark.run("text") { request(:get, "/text") }
79
+ Benchmark.run("simple") { request(:get, "/simple") }
80
80
 
81
- Benchmark.ams("serialize_to_string") { request(:get, "/serialize_to_string") }
81
+ Benchmark.run("serialize_to_string") { request(:get, "/serialize_to_string") }
@@ -40,7 +40,7 @@ def benchmark(prefix, serializer, options = {})
40
40
 
41
41
  merged_options = options.merge(each_serializer: serializer)
42
42
 
43
- Benchmark.ams("Panko_#{prefix}_Posts_#{posts.count}") do
43
+ Benchmark.run("Panko_#{prefix}_Posts_#{posts.count}") do
44
44
  Panko::ArraySerializer.new(posts, merged_options).to_json
45
45
  end
46
46
 
@@ -48,7 +48,7 @@ def benchmark(prefix, serializer, options = {})
48
48
  posts = data[:all]
49
49
  posts_50 = data[:small]
50
50
 
51
- Benchmark.ams("Panko_#{prefix}_Posts_50") do
51
+ Benchmark.run("Panko_#{prefix}_Posts_50") do
52
52
  Panko::ArraySerializer.new(posts_50, merged_options).to_json
53
53
  end
54
54
  end
@@ -32,7 +32,7 @@ def benchmark(prefix, serializer, options = {})
32
32
 
33
33
  merged_options = options.merge(each_serializer: serializer)
34
34
 
35
- Benchmark.ams("Panko_#{prefix}_Posts_#{posts.count}") do
35
+ Benchmark.run("Panko_#{prefix}_Posts_#{posts.count}") do
36
36
  Panko::ArraySerializer.new(posts, merged_options).to_a
37
37
  end
38
38
 
@@ -40,7 +40,7 @@ def benchmark(prefix, serializer, options = {})
40
40
  posts = data[:all]
41
41
  posts_50 = data[:small]
42
42
 
43
- Benchmark.ams("Panko_#{prefix}_Posts_50") do
43
+ Benchmark.run("Panko_#{prefix}_Posts_50") do
44
44
  Panko::ArraySerializer.new(posts_50, merged_options).to_a
45
45
  end
46
46
 
@@ -50,7 +50,7 @@ def benchmark(prefix, serializer, options = {})
50
50
  posts = data[:all]
51
51
  posts_50 = data[:small]
52
52
 
53
- Benchmark.ams("Panko_Reused_#{prefix}_Posts_#{posts.count}") do
53
+ Benchmark.run("Panko_Reused_#{prefix}_Posts_#{posts.count}") do
54
54
  posts_array_serializer.serialize posts
55
55
  end
56
56
 
@@ -58,7 +58,7 @@ def benchmark(prefix, serializer, options = {})
58
58
  posts = data[:all]
59
59
  posts_50 = data[:small]
60
60
 
61
- Benchmark.ams("Panko_Reused_#{prefix}_Posts_50") do
61
+ Benchmark.run("Panko_Reused_#{prefix}_Posts_50") do
62
62
  posts_array_serializer.serialize posts_50
63
63
  end
64
64
  end
data/benchmarks/sanity.rb CHANGED
@@ -40,7 +40,7 @@ def benchmark(prefix, serializer, options = {})
40
40
 
41
41
  merged_options = options.merge(each_serializer: serializer)
42
42
 
43
- Benchmark.ams("Panko_#{prefix}_Posts_#{posts.count}") do
43
+ Benchmark.run("Panko_#{prefix}_Posts_#{posts.count}") do
44
44
  Panko::ArraySerializer.new(posts, merged_options).to_json
45
45
  end
46
46
 
@@ -48,20 +48,14 @@ def benchmark(prefix, serializer, options = {})
48
48
  posts = data[:all]
49
49
  posts_50 = data[:small]
50
50
 
51
- Benchmark.ams("Panko_#{prefix}_Posts_50") do
51
+ Benchmark.run("Panko_#{prefix}_Posts_50") do
52
52
  Panko::ArraySerializer.new(posts_50, merged_options).to_json
53
53
  end
54
54
  end
55
55
 
56
- #puts "Waiting .. #{Process.pid}"
57
- #gets.chomp
58
56
 
59
- #puts "Starting!"
57
+
60
58
 
61
59
  benchmark 'SimpleWithMethodCall', PostFastWithMethodCallSerializer
62
60
  benchmark "HasOne", PostWithHasOneFastSerializer
63
61
  benchmark "Simple", PostFastSerializer
64
-
65
- # benchmark 'SimpleWithMethodCall', PostFastWithMethodCallSerializer
66
- # benchmark 'Except', PostWithHasOneFastSerializer, except: [:title]
67
- # benchmark 'Include', PostWithHasOneFastSerializer, include: [:id, :body, :author_id, :author]
@@ -5,11 +5,11 @@ def ar_type_convert(type_klass, from, to)
5
5
  converter = type_klass.new
6
6
  assert type_klass.name, converter.type_cast_from_database(from), to
7
7
 
8
- Benchmark.ams("#{type_klass.name}_TypeCast") do
8
+ Benchmark.run("#{type_klass.name}_TypeCast") do
9
9
  converter.type_cast_from_database(from)
10
10
  end
11
11
 
12
- Benchmark.ams("#{type_klass.name}_NoTypeCast") do
12
+ Benchmark.run("#{type_klass.name}_NoTypeCast") do
13
13
  converter.type_cast_from_database(to)
14
14
  end
15
15
  end
@@ -22,7 +22,7 @@ def utc_ar_time
22
22
  type = ActiveRecord::ConnectionAdapters::PostgreSQL::OID::DateTime.new
23
23
  converter = ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter.new(type)
24
24
 
25
- Benchmark.ams("#{tz}_#{type.class.name}_TypeCast") do
25
+ Benchmark.run("#{tz}_#{type.class.name}_TypeCast") do
26
26
  converter.type_cast_from_database(from).iso8601
27
27
  end
28
28
  end
@@ -35,7 +35,7 @@ def db_ar_time
35
35
 
36
36
  from = "2017-07-10 09:26:40.937392"
37
37
 
38
- Benchmark.ams("ActiveRecord_Time_TypeCast_WithISO8601") do
38
+ Benchmark.run("ActiveRecord_Time_TypeCast_WithISO8601") do
39
39
  converter.type_cast_from_database(from).iso8601
40
40
  end
41
41
  end
@@ -5,11 +5,11 @@ def panko_type_convert(type_klass, from, to)
5
5
  converter = type_klass.new
6
6
  assert "#{type_klass.name}", Panko::_type_cast(converter, from), to
7
7
 
8
- Benchmark.ams("#{type_klass.name}_TypeCast") do
8
+ Benchmark.run("#{type_klass.name}_TypeCast") do
9
9
  Panko::_type_cast(converter, from)
10
10
  end
11
11
 
12
- Benchmark.ams("#{type_klass.name}_NoTypeCast") do
12
+ Benchmark.run("#{type_klass.name}_NoTypeCast") do
13
13
  Panko::_type_cast(converter, to)
14
14
  end
15
15
  end
@@ -25,11 +25,11 @@ def utc_panko_time
25
25
 
26
26
  to = Panko::_type_cast(converter, from)
27
27
 
28
- Benchmark.ams("#{tz}_#{type.class.name}_TypeCast") do
28
+ Benchmark.run("#{tz}_#{type.class.name}_TypeCast") do
29
29
  Panko::_type_cast(converter, from)
30
30
  end
31
31
 
32
- Benchmark.ams("#{tz}_#{type.class.name}_NoTypeCast") do
32
+ Benchmark.run("#{tz}_#{type.class.name}_NoTypeCast") do
33
33
  Panko::_type_cast(converter, to)
34
34
  end
35
35
  end
@@ -40,7 +40,7 @@ def db_panko_time
40
40
 
41
41
  from = "2017-07-10 09:26:40.937392"
42
42
 
43
- Benchmark.ams("Panko_Time_TypeCast") do
43
+ Benchmark.run("Panko_Time_TypeCast") do
44
44
  Panko::_type_cast(converter, from)
45
45
  end
46
46
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  static ID attributes_id;
4
4
  static ID types_id;
5
+ static ID additional_types_id;
5
6
  static ID values_id;
6
7
  static ID delegate_hash_id;
7
8
 
@@ -30,13 +31,16 @@ VALUE panko_read_lazy_attributes_hash(VALUE object) {
30
31
 
31
32
  void panko_read_types_and_value(VALUE attributes_hash,
32
33
  VALUE* types,
34
+ VALUE* additional_types,
33
35
  VALUE* values) {
34
36
  *types = rb_ivar_get(attributes_hash, types_id);
37
+ *additional_types = rb_ivar_get(attributes_hash, additional_types_id);
35
38
  *values = rb_ivar_get(attributes_hash, values_id);
36
39
  }
37
40
 
38
41
  VALUE panko_each_attribute(VALUE obj,
39
42
  VALUE attributes,
43
+ VALUE aliases,
40
44
  EachAttributeFunc func,
41
45
  VALUE context) {
42
46
  volatile VALUE attributes_hash, delegate_hash;
@@ -50,11 +54,16 @@ VALUE panko_each_attribute(VALUE obj,
50
54
  delegate_hash = rb_ivar_get(attributes_hash, delegate_hash_id);
51
55
  bool tryToReadFromDelegateHash = RHASH_SIZE(delegate_hash) > 0;
52
56
 
53
- VALUE types, values;
54
- panko_read_types_and_value(attributes_hash, &types, &values);
57
+ VALUE types, additional_types, values;
58
+ panko_read_types_and_value(attributes_hash, &types, &additional_types,
59
+ &values);
60
+ bool tryToReadFromAdditionalTypes = RHASH_SIZE(additional_types) > 0;
61
+
62
+ bool tryToReadFromAliases = RHASH_SIZE(aliases) > 0;
55
63
 
56
64
  for (i = 0; i < RARRAY_LEN(attributes); i++) {
57
- volatile VALUE member = rb_sym2str(RARRAY_AREF(attributes, i));
65
+ volatile VALUE member_raw = RARRAY_AREF(attributes, i);
66
+ volatile VALUE member = rb_sym2str(member_raw);
58
67
 
59
68
  volatile VALUE value = Qundef;
60
69
  volatile VALUE type_metadata = Qnil;
@@ -72,7 +81,20 @@ VALUE panko_each_attribute(VALUE obj,
72
81
 
73
82
  if (value == Qundef) {
74
83
  value = rb_hash_aref(values, member);
75
- type_metadata = rb_hash_aref(types, member);
84
+
85
+ if (tryToReadFromAdditionalTypes) {
86
+ type_metadata = rb_hash_aref(additional_types, member);
87
+ }
88
+ if (type_metadata == Qnil) {
89
+ type_metadata = rb_hash_aref(types, member);
90
+ }
91
+ }
92
+
93
+ if(tryToReadFromAliases) {
94
+ volatile VALUE alias_name = rb_hash_aref(aliases, member_raw);
95
+ if(alias_name != Qnil) {
96
+ member = rb_sym2str(alias_name);
97
+ }
76
98
  }
77
99
 
78
100
  func(obj, member, value, type_metadata, context);
@@ -86,6 +108,7 @@ void panko_init_attributes_iterator(VALUE mPanko) {
86
108
  delegate_hash_id = rb_intern("@delegate_hash");
87
109
  values_id = rb_intern("@values");
88
110
  types_id = rb_intern("@types");
111
+ additional_types_id = rb_intern("@additional_types");
89
112
  type_id = rb_intern("@type");
90
113
  value_before_type_cast_id = rb_intern("@value_before_type_cast");
91
114
  }
@@ -11,6 +11,7 @@ typedef void (*EachAttributeFunc)(VALUE object,
11
11
 
12
12
  extern VALUE panko_each_attribute(VALUE object,
13
13
  VALUE attributes,
14
+ VALUE aliases,
14
15
  EachAttributeFunc func,
15
16
  VALUE context);
16
17
 
@@ -48,16 +48,16 @@ void panko_attributes_iter(VALUE object,
48
48
  VALUE name,
49
49
  VALUE value,
50
50
  VALUE type_metadata,
51
- VALUE context) {
52
- write_value(context, name, value, type_metadata);
51
+ VALUE str_writer) {
52
+ write_value(str_writer, name, value, type_metadata);
53
53
  }
54
54
 
55
55
  void serialize_fields(VALUE subject,
56
56
  VALUE str_writer,
57
57
  SerializationDescriptor descriptor,
58
58
  VALUE context) {
59
- panko_each_attribute(subject, descriptor->fields, panko_attributes_iter,
60
- str_writer);
59
+ panko_each_attribute(subject, descriptor->fields, descriptor->aliases,
60
+ panko_attributes_iter, str_writer);
61
61
 
62
62
  serialize_method_fields(subject, str_writer, descriptor, context);
63
63
  }
@@ -18,6 +18,7 @@ static void serialization_descriptor_free(void* ptr) {
18
18
  sd->method_fields = Qnil;
19
19
  sd->has_one_associations = Qnil;
20
20
  sd->has_many_associations = Qnil;
21
+ sd->aliases = Qnil;
21
22
  }
22
23
 
23
24
  void serialization_descriptor_mark(SerializationDescriptor data) {
@@ -27,6 +28,7 @@ void serialization_descriptor_mark(SerializationDescriptor data) {
27
28
  rb_gc_mark(data->method_fields);
28
29
  rb_gc_mark(data->has_one_associations);
29
30
  rb_gc_mark(data->has_many_associations);
31
+ rb_gc_mark(data->aliases);
30
32
  }
31
33
 
32
34
  static VALUE serialization_descriptor_new(int argc, VALUE* argv, VALUE self) {
@@ -38,6 +40,7 @@ static VALUE serialization_descriptor_new(int argc, VALUE* argv, VALUE self) {
38
40
  sd->method_fields = Qnil;
39
41
  sd->has_one_associations = Qnil;
40
42
  sd->has_many_associations = Qnil;
43
+ sd->aliases = Qnil;
41
44
 
42
45
  return Data_Wrap_Struct(cSerializationDescriptor,
43
46
  serialization_descriptor_mark,
@@ -126,6 +129,17 @@ VALUE serialization_descriptor_type_aref(VALUE self, VALUE type) {
126
129
  return sd->serializer_type;
127
130
  }
128
131
 
132
+ VALUE serialization_descriptor_aliases_set(VALUE self, VALUE aliases) {
133
+ SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
134
+ sd->aliases = aliases;
135
+ return Qnil;
136
+ }
137
+
138
+ VALUE serialization_descriptor_aliases_aref(VALUE self, VALUE aliases) {
139
+ SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
140
+ return sd->aliases;
141
+ }
142
+
129
143
  // Exposing this for testing
130
144
  VALUE serialization_descriptor_build_serializer(VALUE self) {
131
145
  SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
@@ -165,8 +179,13 @@ void panko_init_serialization_descriptor(VALUE mPanko) {
165
179
 
166
180
  rb_define_method(cSerializationDescriptor,
167
181
  "type=", serialization_descriptor_type_set, 1);
182
+ rb_define_method(cSerializationDescriptor, "type",
183
+ serialization_descriptor_type_aref, 0);
184
+
168
185
  rb_define_method(cSerializationDescriptor,
169
- "type", serialization_descriptor_type_aref, 0);
186
+ "aliases=", serialization_descriptor_aliases_set, 1);
187
+ rb_define_method(cSerializationDescriptor, "aliases",
188
+ serialization_descriptor_aliases_aref, 0);
170
189
 
171
190
  rb_define_method(cSerializationDescriptor, "build_serializer",
172
191
  serialization_descriptor_build_serializer, 0);
@@ -12,6 +12,7 @@ typedef struct _SerializationDescriptor {
12
12
  // Metadata
13
13
  VALUE fields;
14
14
  VALUE method_fields;
15
+ VALUE aliases;
15
16
  VALUE has_one_associations;
16
17
  VALUE has_many_associations;
17
18
  } * SerializationDescriptor;
@@ -26,6 +26,8 @@ module Panko
26
26
  backend.has_many_associations = descriptor.has_many_associations
27
27
  backend.has_one_associations = descriptor.has_one_associations
28
28
 
29
+ backend.aliases = descriptor.aliases
30
+
29
31
  backend
30
32
  end
31
33
 
@@ -108,10 +110,5 @@ module Panko
108
110
 
109
111
  fields
110
112
  end
111
-
112
-
113
- def self.resolve_serializer(serializer)
114
- Object.const_get(serializer.name)
115
- end
116
113
  end
117
114
  end
@@ -9,6 +9,7 @@ module Panko
9
9
  base._descriptor = Panko::SerializationDescriptor.new
10
10
  base._descriptor.type = base
11
11
 
12
+ base._descriptor.aliases = {}
12
13
  base._descriptor.fields = []
13
14
  base._descriptor.method_fields = []
14
15
  base._descriptor.has_many_associations = []
@@ -21,6 +22,11 @@ module Panko
21
22
  @_descriptor.fields.push(*attrs).uniq!
22
23
  end
23
24
 
25
+ def aliases(aliases = {})
26
+ @_descriptor.aliases = aliases
27
+ attributes(*aliases.keys)
28
+ end
29
+
24
30
  def method_added(method)
25
31
  return if @_descriptor.nil?
26
32
  @_descriptor.fields.delete(method)
@@ -28,7 +34,7 @@ module Panko
28
34
  end
29
35
 
30
36
  def has_one(name, options)
31
- serializer_const = Panko::SerializationDescriptor.resolve_serializer(options[:serializer])
37
+ serializer_const = options[:serializer]
32
38
 
33
39
  @_descriptor.has_one_associations << [
34
40
  name,
@@ -37,7 +43,7 @@ module Panko
37
43
  end
38
44
 
39
45
  def has_many(name, options)
40
- serializer_const = Panko::SerializationDescriptor.resolve_serializer(options[:serializer])
46
+ serializer_const = options[:serializer] || options[:each_serializer]
41
47
 
42
48
  @_descriptor.has_many_associations << [
43
49
  name,
data/lib/panko/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Panko
3
- VERSION = "0.1.6"
3
+ VERSION = "0.1.7"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: panko_serializer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yosi Attias
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-17 00:00:00.000000000 Z
11
+ date: 2017-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -110,7 +110,6 @@ files:
110
110
  - benchmarks/setup.rb
111
111
  - benchmarks/type_casts/bm_active_record.rb
112
112
  - benchmarks/type_casts/bm_panko.rb
113
- - benchmarks/type_casts/bm_pg.rb
114
113
  - benchmarks/type_casts/support.rb
115
114
  - ext/panko_serializer/attributes_iterator.c
116
115
  - ext/panko_serializer/attributes_iterator.h
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
- require_relative "./support"
3
-
4
- def pg_type_convert(type_klass, from, to)
5
- converter = type_klass.new
6
- assert type_klass.name, converter.decode(from), to
7
-
8
- Benchmark.ams("#{type_klass.name}_TypeCast") do
9
- converter.decode(from)
10
- end
11
- end
12
-
13
- def pg_time
14
- decoder = PG::TextDecoder::TimestampWithoutTimeZone.new
15
-
16
- from = "2017-07-10 09:26:40.937392"
17
-
18
- Benchmark.ams("#{decoder.class.name}_TypeCast") do
19
- decoder.decode(from)
20
- end
21
-
22
- Benchmark.ams("#{decoder.class.name}_TypeCast_InTimeZone") do
23
- decoder.decode(from).in_time_zone
24
- end
25
- end
26
-
27
-
28
-
29
-
30
- pg_type_convert PG::TextDecoder::Integer, "1", 1
31
- pg_type_convert PG::TextDecoder::Float, "1.23", 1.23
32
- pg_type_convert PG::TextDecoder::Float, "Infinity", ::Float::INFINITY
33
- pg_type_convert PG::TextDecoder::Float, "-Infinity", ::Float::INFINITY
34
- pg_type_convert PG::TextDecoder::Float, "NaN", ::Float::NaN
35
- pg_time