panko_serializer 0.5.5 → 0.5.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.clang-format +35 -4
- data/Gemfile +1 -1
- data/benchmarks/bm_ams_0_10.rb +0 -6
- data/docs/performance.md +15 -21
- data/ext/panko_serializer/attributes_writer/active_record.c +17 -26
- data/ext/panko_serializer/attributes_writer/active_record.h +5 -5
- data/ext/panko_serializer/attributes_writer/{writer.c → attributes_writer.c} +9 -9
- data/ext/panko_serializer/attributes_writer/{writer.h → attributes_writer.h} +4 -4
- data/ext/panko_serializer/attributes_writer/plain.c +4 -6
- data/ext/panko_serializer/attributes_writer/plain.h +4 -4
- data/ext/panko_serializer/panko_serializer.h +1 -1
- data/ext/panko_serializer/serialization_descriptor/serialization_descriptor.c +0 -2
- data/ext/panko_serializer/serialization_descriptor/serialization_descriptor.h +1 -1
- data/lib/panko/response.rb +1 -1
- data/lib/panko/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b5c1f172b419c50aea9cc47c6f5dbc52972856f08aef2afc1be72da7d051a167
|
4
|
+
data.tar.gz: 73ca52128f528f7d6b2c76ae34fe765a224ee0e8494a502c7550e873b6a50eaf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9867ec56395cca5bb634385e362074f38b23eba16e81d2145128be32cb09224643be8ba998e46b8b940797e4c4599b3c8da6edb36dc81deeb78ae6e4dcb1b39c
|
7
|
+
data.tar.gz: e10796a79f2a049da21a9895bff29191182989a06b9b31a81aec09f86a4899794c2b49a163069d8fcadcc85d47d86489ed6d97fc643fdaf7a4eece22b71f9058
|
data/.clang-format
CHANGED
@@ -17,7 +17,7 @@ AllowShortLoopsOnASingleLine: false
|
|
17
17
|
AlwaysBreakAfterDefinitionReturnType: None
|
18
18
|
AlwaysBreakAfterReturnType: None
|
19
19
|
AlwaysBreakBeforeMultilineStrings: true
|
20
|
-
AlwaysBreakTemplateDeclarations:
|
20
|
+
AlwaysBreakTemplateDeclarations: Yes
|
21
21
|
BinPackArguments: true
|
22
22
|
BinPackParameters: false
|
23
23
|
BraceWrapping:
|
@@ -39,6 +39,7 @@ BraceWrapping:
|
|
39
39
|
BreakBeforeBinaryOperators: None
|
40
40
|
BreakBeforeBraces: Attach
|
41
41
|
BreakBeforeInheritanceComma: false
|
42
|
+
BreakInheritanceList: BeforeColon
|
42
43
|
BreakBeforeTernaryOperators: true
|
43
44
|
BreakConstructorInitializersBeforeComma: false
|
44
45
|
BreakConstructorInitializers: BeforeColon
|
@@ -81,20 +82,46 @@ MacroBlockBegin: ''
|
|
81
82
|
MacroBlockEnd: ''
|
82
83
|
MaxEmptyLinesToKeep: 1
|
83
84
|
NamespaceIndentation: None
|
85
|
+
ObjCBinPackProtocolList: Never
|
84
86
|
ObjCBlockIndentWidth: 2
|
85
87
|
ObjCSpaceAfterProperty: false
|
86
|
-
ObjCSpaceBeforeProtocolList:
|
88
|
+
ObjCSpaceBeforeProtocolList: true
|
87
89
|
PenaltyBreakAssignment: 2
|
88
90
|
PenaltyBreakBeforeFirstCallParameter: 1
|
89
91
|
PenaltyBreakComment: 300
|
90
92
|
PenaltyBreakFirstLessLess: 120
|
91
93
|
PenaltyBreakString: 1000
|
94
|
+
PenaltyBreakTemplateDeclaration: 10
|
92
95
|
PenaltyExcessCharacter: 1000000
|
93
96
|
PenaltyReturnTypeOnItsOwnLine: 200
|
94
97
|
PointerAlignment: Left
|
95
98
|
RawStringFormats:
|
96
|
-
-
|
97
|
-
|
99
|
+
- Language: Cpp
|
100
|
+
Delimiters:
|
101
|
+
- cc
|
102
|
+
- CC
|
103
|
+
- cpp
|
104
|
+
- Cpp
|
105
|
+
- CPP
|
106
|
+
- 'c++'
|
107
|
+
- 'C++'
|
108
|
+
CanonicalDelimiter: ''
|
109
|
+
BasedOnStyle: google
|
110
|
+
- Language: TextProto
|
111
|
+
Delimiters:
|
112
|
+
- pb
|
113
|
+
- PB
|
114
|
+
- proto
|
115
|
+
- PROTO
|
116
|
+
EnclosingFunctions:
|
117
|
+
- EqualsProto
|
118
|
+
- EquivToProto
|
119
|
+
- PARSE_PARTIAL_TEXT_PROTO
|
120
|
+
- PARSE_TEST_PROTO
|
121
|
+
- PARSE_TEXT_PROTO
|
122
|
+
- ParseTextOrDie
|
123
|
+
- ParseTextProtoOrDie
|
124
|
+
CanonicalDelimiter: ''
|
98
125
|
BasedOnStyle: google
|
99
126
|
ReflowComments: true
|
100
127
|
SortIncludes: true
|
@@ -102,7 +129,11 @@ SortUsingDeclarations: true
|
|
102
129
|
SpaceAfterCStyleCast: false
|
103
130
|
SpaceAfterTemplateKeyword: true
|
104
131
|
SpaceBeforeAssignmentOperators: true
|
132
|
+
SpaceBeforeCpp11BracedList: false
|
133
|
+
SpaceBeforeCtorInitializerColon: true
|
134
|
+
SpaceBeforeInheritanceColon: true
|
105
135
|
SpaceBeforeParens: ControlStatements
|
136
|
+
SpaceBeforeRangeBasedForLoopColon: true
|
106
137
|
SpaceInEmptyParentheses: false
|
107
138
|
SpacesBeforeTrailingComments: 2
|
108
139
|
SpacesInAngles: false
|
data/Gemfile
CHANGED
data/benchmarks/bm_ams_0_10.rb
CHANGED
@@ -48,9 +48,3 @@ benchmark_ams "Attributes_HasOne", AmsPostWithHasOneFastSerializer
|
|
48
48
|
benchmark_ams "Attributes_Except", AmsPostWithHasOneFastSerializer, except: [:title]
|
49
49
|
benchmark_ams "Attributes_Only", AmsPostWithHasOneFastSerializer, only: [:id, :body, :author_id, :author]
|
50
50
|
|
51
|
-
ActiveModel::Serializer.config.adapter = :json_api
|
52
|
-
|
53
|
-
benchmark_ams "JsonAPI_Simple", AmsPostFastSerializer
|
54
|
-
benchmark_ams "JsonAPI_HasOne", AmsPostWithHasOneFastSerializer
|
55
|
-
benchmark_ams "JsonAPI_Except", AmsPostWithHasOneFastSerializer, except: [:title]
|
56
|
-
benchmark_ams "JsonAPI_Only", AmsPostWithHasOneFastSerializer, only: [:id, :body, :author_id, :author]
|
data/docs/performance.md
CHANGED
@@ -4,32 +4,26 @@ The performance of Panko is measured using microbenchmarks and load testing.
|
|
4
4
|
|
5
5
|
## Microbenchmarks
|
6
6
|
|
7
|
-
The following microbenchmarks are run on MacBook Pro (Retina, 15-inch,
|
8
|
-
demonstrating the performance of ActiveModelSerializers 0.
|
9
|
-
|
10
|
-
|
11
|
-
Benchmark | AMS ip/s | Panko ip/s
|
12
|
-
---------------------------------------|----------|-----------------
|
13
|
-
| Simple_Posts_2300 | 25.81 | 135.29 |
|
14
|
-
| Simple_Posts_50 | 1,248.39 | 6,518.68 |
|
15
|
-
| HasOne_Posts_2300 | 11.33 | 73.42 |
|
16
|
-
| HasOne_Posts_50 | 523.14 | 4,985.41 |
|
17
|
-
|
18
|
-
> The corresponding benchmarks are `benchmarks/bm_active_model_serializers.rb` and `benchmarks/bm_panko_json.rb`
|
7
|
+
The following microbenchmarks are run on MacBook Pro (Retina, 15-inch, 2017), Ruby 2.5.1 with Rails 5.2.1
|
8
|
+
demonstrating the performance of ActiveModelSerializers 0.10.7 and Panko 0.5.6
|
19
9
|
|
10
|
+
| Benchmark | AMS ip/s | Panko ip/s |
|
11
|
+
| ----------------- | -------- | ---------- |
|
12
|
+
| Simple_Posts_2300 | 9.47 | 185.9 |
|
13
|
+
| Simple_Posts_50 | 450.49 | 9,237.66 |
|
14
|
+
| HasOne_Posts_2300 | 4.27 | 104.39 |
|
15
|
+
| HasOne_Posts_50 | 219.67 | 4,901.09 |
|
20
16
|
|
21
17
|
## Real-world benchmark
|
22
18
|
|
23
19
|
The real-world benchmark here is endpoint which serializes 7,884 entries with 48 attributes and no associations.
|
24
20
|
The benchmark took place in environment that simulates production environment and run using `wrk` from machine on the same cluster.
|
25
21
|
|
22
|
+
| Metric | AMS | Panko |
|
23
|
+
| ------------------ | ----- | ----- |
|
24
|
+
| Avg Response Time | 4.89s | 1.48s |
|
25
|
+
| Max Response Time | 5.42s | 1.83s |
|
26
|
+
| 99th Response Time | 5.42s | 1.74s |
|
27
|
+
| Total Requests | 61 | 202 |
|
26
28
|
|
27
|
-
|
28
|
-
------------ |------------ | -------------
|
29
|
-
Avg Response Time| 4.89s| 1.48s|
|
30
|
-
Max Response Time| 5.42s| 1.83s|
|
31
|
-
99th Response Time| 5.42s| 1.74s|
|
32
|
-
Total Requests| 61| 202|
|
33
|
-
|
34
|
-
|
35
|
-
*Thanks to [Bringg](https://www.bringg.com) for providing the infrastructrue for the benchmarks*
|
29
|
+
_Thanks to [Bringg](https://www.bringg.com) for providing the infrastructure for the benchmarks_
|
@@ -21,15 +21,6 @@ VALUE panko_read_lazy_attributes_hash(VALUE object) {
|
|
21
21
|
return lazy_attributes_hash;
|
22
22
|
}
|
23
23
|
|
24
|
-
void panko_read_types_and_value(VALUE attributes_hash,
|
25
|
-
VALUE* types,
|
26
|
-
VALUE* additional_types,
|
27
|
-
VALUE* values) {
|
28
|
-
*types = rb_ivar_get(attributes_hash, types_id);
|
29
|
-
*additional_types = rb_ivar_get(attributes_hash, additional_types_id);
|
30
|
-
*values = rb_ivar_get(attributes_hash, values_id);
|
31
|
-
}
|
32
|
-
|
33
24
|
void read_attribute_from_hash(VALUE attributes_hash,
|
34
25
|
VALUE member,
|
35
26
|
volatile VALUE* value,
|
@@ -66,25 +57,27 @@ struct attributes init_context(VALUE obj) {
|
|
66
57
|
attributes_ctx.shouldReadFromHash = false;
|
67
58
|
attributes_ctx.tryToReadFromAdditionalTypes = false;
|
68
59
|
|
69
|
-
volatile VALUE
|
60
|
+
volatile VALUE lazy_attributes_hash = panko_read_lazy_attributes_hash(obj);
|
70
61
|
|
71
|
-
if (RB_TYPE_P(
|
72
|
-
attributes_ctx.attributes_hash =
|
62
|
+
if (RB_TYPE_P(lazy_attributes_hash, T_HASH)) {
|
63
|
+
attributes_ctx.attributes_hash = lazy_attributes_hash;
|
73
64
|
attributes_ctx.shouldReadFromHash = true;
|
74
65
|
} else {
|
75
66
|
volatile VALUE delegate_hash =
|
76
|
-
rb_ivar_get(
|
77
|
-
|
67
|
+
rb_ivar_get(lazy_attributes_hash, delegate_hash_id);
|
68
|
+
|
69
|
+
if (PANKO_EMPTY_HASH(delegate_hash) == false) {
|
78
70
|
attributes_ctx.attributes_hash = delegate_hash;
|
79
71
|
attributes_ctx.shouldReadFromHash = true;
|
80
72
|
}
|
81
73
|
|
82
|
-
|
83
|
-
|
84
|
-
&attributes_ctx.values);
|
74
|
+
attributes_ctx.types = rb_ivar_get(lazy_attributes_hash, types_id);
|
75
|
+
attributes_ctx.values = rb_ivar_get(lazy_attributes_hash, values_id);
|
85
76
|
|
77
|
+
attributes_ctx.additional_types =
|
78
|
+
rb_ivar_get(lazy_attributes_hash, additional_types_id);
|
86
79
|
attributes_ctx.tryToReadFromAdditionalTypes =
|
87
|
-
|
80
|
+
PANKO_EMPTY_HASH(attributes_ctx.additional_types) == false;
|
88
81
|
}
|
89
82
|
|
90
83
|
return attributes_ctx;
|
@@ -101,13 +94,13 @@ VALUE read_attribute(struct attributes attributes_ctx, Attribute attribute) {
|
|
101
94
|
}
|
102
95
|
}
|
103
96
|
|
104
|
-
if (value == Qundef && attributes_ctx.shouldReadFromHash) {
|
97
|
+
if (value == Qundef && attributes_ctx.shouldReadFromHash == true) {
|
105
98
|
read_attribute_from_hash(attributes_ctx.attributes_hash, member, &value,
|
106
99
|
&attribute->type);
|
107
100
|
}
|
108
101
|
|
109
102
|
if (NIL_P(attribute->type) && !NIL_P(value)) {
|
110
|
-
if (attributes_ctx.tryToReadFromAdditionalTypes) {
|
103
|
+
if (attributes_ctx.tryToReadFromAdditionalTypes == true) {
|
111
104
|
attribute->type = rb_hash_aref(attributes_ctx.additional_types, member);
|
112
105
|
}
|
113
106
|
|
@@ -123,10 +116,10 @@ VALUE read_attribute(struct attributes attributes_ctx, Attribute attribute) {
|
|
123
116
|
return value;
|
124
117
|
}
|
125
118
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
119
|
+
void active_record_attributes_writer(VALUE obj,
|
120
|
+
VALUE attributes,
|
121
|
+
EachAttributeFunc func,
|
122
|
+
VALUE writer) {
|
130
123
|
long i;
|
131
124
|
struct attributes attributes_ctx = init_context(obj);
|
132
125
|
volatile VALUE record_class = CLASS_OF(obj);
|
@@ -140,8 +133,6 @@ VALUE active_record_attributes_writer(VALUE obj,
|
|
140
133
|
|
141
134
|
func(writer, attr_name_for_serialization(attribute), value);
|
142
135
|
}
|
143
|
-
|
144
|
-
return Qnil;
|
145
136
|
}
|
146
137
|
|
147
138
|
void init_active_record_attributes_writer(VALUE mPanko) {
|
@@ -3,14 +3,14 @@
|
|
3
3
|
#include <ruby.h>
|
4
4
|
#include <stdbool.h>
|
5
5
|
|
6
|
+
#include "../common.h"
|
6
7
|
#include "common.h"
|
7
8
|
#include "serialization_descriptor/attribute.h"
|
8
9
|
#include "type_cast/type_cast.h"
|
9
|
-
#include "../common.h"
|
10
10
|
|
11
|
-
extern
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
extern void active_record_attributes_writer(VALUE object,
|
12
|
+
VALUE attributes,
|
13
|
+
EachAttributeFunc func,
|
14
|
+
VALUE context);
|
15
15
|
|
16
16
|
void init_active_record_attributes_writer(VALUE mPanko);
|
@@ -1,11 +1,11 @@
|
|
1
|
-
#include "
|
1
|
+
#include "attributes_writer.h"
|
2
2
|
|
3
3
|
static bool types_initialized = false;
|
4
4
|
static VALUE ar_base_type = Qundef;
|
5
5
|
|
6
|
-
|
6
|
+
VALUE init_types(VALUE v) {
|
7
7
|
if (types_initialized == true) {
|
8
|
-
return;
|
8
|
+
return Qundef;
|
9
9
|
}
|
10
10
|
|
11
11
|
types_initialized = true;
|
@@ -13,6 +13,8 @@ void init_types(VALUE v) {
|
|
13
13
|
volatile VALUE ar_type =
|
14
14
|
rb_const_get_at(rb_cObject, rb_intern("ActiveRecord"));
|
15
15
|
ar_base_type = rb_const_get_at(ar_type, rb_intern("Base"));
|
16
|
+
|
17
|
+
return Qundef;
|
16
18
|
}
|
17
19
|
|
18
20
|
AttributesWriter create_attributes_writer(VALUE subject) {
|
@@ -33,12 +35,10 @@ AttributesWriter create_attributes_writer(VALUE subject) {
|
|
33
35
|
return create_empty_attributes_writer();
|
34
36
|
}
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
return Qnil;
|
41
|
-
}
|
38
|
+
void empty_write_attributes(VALUE obj,
|
39
|
+
VALUE attributes,
|
40
|
+
EachAttributeFunc func,
|
41
|
+
VALUE writer) {}
|
42
42
|
|
43
43
|
AttributesWriter create_empty_attributes_writer() {
|
44
44
|
return (AttributesWriter){.object_type = Unknown,
|
@@ -11,10 +11,10 @@ enum ObjectType { Unknown = 0, ActiveRecord = 1, Plain = 2 };
|
|
11
11
|
typedef struct _AttributesWriter {
|
12
12
|
enum ObjectType object_type;
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
void (*write_attributes)(VALUE object,
|
15
|
+
VALUE attributes,
|
16
|
+
EachAttributeFunc func,
|
17
|
+
VALUE context);
|
18
18
|
} AttributesWriter;
|
19
19
|
|
20
20
|
/**
|
@@ -1,9 +1,9 @@
|
|
1
1
|
#include "plain.h"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
void plain_attributes_writer(VALUE obj,
|
4
|
+
VALUE attributes,
|
5
|
+
EachAttributeFunc func,
|
6
|
+
VALUE writer) {
|
7
7
|
long i;
|
8
8
|
for (i = 0; i < RARRAY_LEN(attributes); i++) {
|
9
9
|
volatile VALUE raw_attribute = RARRAY_AREF(attributes, i);
|
@@ -12,6 +12,4 @@ VALUE plain_attributes_writer(VALUE obj,
|
|
12
12
|
|
13
13
|
func(writer, attr_name_for_serialization(attribute), value);
|
14
14
|
}
|
15
|
-
|
16
|
-
return Qnil;
|
17
15
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#include <ruby.h>
|
2
2
|
|
3
|
-
#include "attributes_writer/
|
3
|
+
#include "attributes_writer/attributes_writer.h"
|
4
4
|
#include "serialization_descriptor/association.h"
|
5
5
|
#include "serialization_descriptor/attribute.h"
|
6
6
|
#include "serialization_descriptor/serialization_descriptor.h"
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
VALUE cSerializationDescriptor;
|
4
4
|
|
5
|
-
static ID context_id;
|
6
5
|
static ID object_id;
|
7
6
|
static ID sc_id;
|
8
7
|
|
@@ -59,7 +58,6 @@ void sd_set_writer(SerializationDescriptor sd, VALUE subject) {
|
|
59
58
|
sd->attributes_writer = create_attributes_writer(subject);
|
60
59
|
}
|
61
60
|
|
62
|
-
|
63
61
|
VALUE sd_serializer_set(VALUE self, VALUE serializer) {
|
64
62
|
SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
|
65
63
|
|
data/lib/panko/response.rb
CHANGED
@@ -51,7 +51,7 @@ module Panko
|
|
51
51
|
def write(writer, data, key = nil)
|
52
52
|
return write_array(writer, data, key) if data.is_a?(Array)
|
53
53
|
|
54
|
-
return write_object(writer, data) if data.is_a?(Hash)
|
54
|
+
return write_object(writer, data, key) if data.is_a?(Hash)
|
55
55
|
|
56
56
|
write_value(writer, data, key)
|
57
57
|
end
|
data/lib/panko/version.rb
CHANGED
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.5.
|
4
|
+
version: 0.5.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yosi Attias
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-10-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oj
|
@@ -67,6 +67,8 @@ files:
|
|
67
67
|
- docs/response-bag.md
|
68
68
|
- ext/panko_serializer/attributes_writer/active_record.c
|
69
69
|
- ext/panko_serializer/attributes_writer/active_record.h
|
70
|
+
- ext/panko_serializer/attributes_writer/attributes_writer.c
|
71
|
+
- ext/panko_serializer/attributes_writer/attributes_writer.h
|
70
72
|
- ext/panko_serializer/attributes_writer/common.c
|
71
73
|
- ext/panko_serializer/attributes_writer/common.h
|
72
74
|
- ext/panko_serializer/attributes_writer/plain.c
|
@@ -75,8 +77,6 @@ files:
|
|
75
77
|
- ext/panko_serializer/attributes_writer/type_cast/time_conversion.h
|
76
78
|
- ext/panko_serializer/attributes_writer/type_cast/type_cast.c
|
77
79
|
- ext/panko_serializer/attributes_writer/type_cast/type_cast.h
|
78
|
-
- ext/panko_serializer/attributes_writer/writer.c
|
79
|
-
- ext/panko_serializer/attributes_writer/writer.h
|
80
80
|
- ext/panko_serializer/common.h
|
81
81
|
- ext/panko_serializer/extconf.rb
|
82
82
|
- ext/panko_serializer/panko_serializer.c
|