Skip to content

Commit

Permalink
Add fast-path for type-casting Jsonb/Timestamp
Browse files Browse the repository at this point in the history
Add support for:

- ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Jsonb
- ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Timestamp

Benchmark - running `benchmarks/sanity` with ITEMS_COUNT of 2300, adding `jsonb` column to Posts.
```
Master:
{"label":"Panko_Simple_Posts_2300","ips":"87.56","allocs":"20721/2"}
{"label":"Panko_Simple_Posts_50","ips":"4,266.99","allocs":"469/2"}
{"label":"Panko_HasOne_Posts_2300","ips":"109.31","allocs":"9227/1"}
{"label":"Panko_HasOne_Posts_50","ips":"5,557.47","allocs":"227/1"}
{"label":"Panko_SimpleWithMethodCall_Posts_2300","ips":"82.25","allocs":"20722/2"}
{"label":"Panko_SimpleWithMethodCall_Posts_50","ips":"3,954.0","allocs":"472/2"}

Branch:
{"label":"Panko_Simple_Posts_2300","ips":"137.27","allocs":"9221/1"}
{"label":"Panko_Simple_Posts_50","ips":"6,605.73","allocs":"219/1"}
{"label":"Panko_HasOne_Posts_2300","ips":"112.41","allocs":"9227/1"}
{"label":"Panko_HasOne_Posts_50","ips":"5,726.94","allocs":"227/1"}
{"label":"Panko_SimpleWithMethodCall_Posts_2300","ips":"124.72","allocs":"9222/1"}
{"label":"Panko_SimpleWithMethodCall_Posts_50","ips":"5,972.18","allocs":"222/1"}
```
  • Loading branch information
yosiat committed Jul 13, 2024
1 parent 10238d4 commit 291d1dc
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
3 changes: 3 additions & 0 deletions benchmarks/type_casts/bm_panko.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ def db_panko_time
if check_if_exists "ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Json"
panko_type_convert ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Json, '{"a":1}', '{"a":1}'
end
if check_if_exists "ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Jsonb"
panko_type_convert ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Jsonb, '{"a":1}', '{"a":1}'
end
if check_if_exists "ActiveRecord::Type::Json"
panko_type_convert ActiveRecord::Type::Json, '{"a":1}', '{"a":1}'
end
Expand Down
17 changes: 17 additions & 0 deletions ext/panko_serializer/attributes_writer/type_cast/type_cast.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ static VALUE ar_pg_integer_type = Qundef;
static VALUE ar_pg_float_type = Qundef;
static VALUE ar_pg_uuid_type = Qundef;
static VALUE ar_pg_json_type = Qundef;
static VALUE ar_pg_jsonb_type = Qundef;
static VALUE ar_pg_array_type = Qundef;
static VALUE ar_pg_date_time_type = Qundef;
static VALUE ar_pg_timestamp_type = Qundef;

static int initiailized = 0;

Expand Down Expand Up @@ -63,10 +66,18 @@ VALUE cache_postgres_type_lookup(VALUE ar) {
ar_pg_json_type = rb_const_get_at(ar_oid, rb_intern("Json"));
}

if (rb_const_defined_at(ar_oid, rb_intern("Jsonb")) == (int)Qtrue) {
ar_pg_jsonb_type = rb_const_get_at(ar_oid, rb_intern("Jsonb"));
}

if (rb_const_defined_at(ar_oid, rb_intern("DateTime")) == (int)Qtrue) {
ar_pg_date_time_type = rb_const_get_at(ar_oid, rb_intern("DateTime"));
}

if (rb_const_defined_at(ar_oid, rb_intern("Timestamp")) == (int)Qtrue) {
ar_pg_timestamp_type = rb_const_get_at(ar_oid, rb_intern("Timestamp"));
}

return Qtrue;
}

Expand Down Expand Up @@ -210,6 +221,7 @@ VALUE cast_integer_type(VALUE value) {

bool is_json_type(VALUE type_klass) {
return ((ar_pg_json_type != Qundef && type_klass == ar_pg_json_type) ||
(ar_pg_jsonb_type != Qundef && type_klass == ar_pg_jsonb_type) ||
(ar_json_type != Qundef && type_klass == ar_json_type));
}

Expand Down Expand Up @@ -250,6 +262,8 @@ bool is_date_time_type(VALUE type_klass) {
return (type_klass == ar_date_time_type) ||
(ar_pg_date_time_type != Qundef &&
type_klass == ar_pg_date_time_type) ||
(ar_pg_timestamp_type != Qundef &&
type_klass == ar_pg_timestamp_type) ||
(ar_time_zone_converter != Qundef &&
type_klass == ar_time_zone_converter);
}
Expand Down Expand Up @@ -377,5 +391,8 @@ void panko_init_type_cast(VALUE mPanko) {
rb_global_variable(&ar_pg_float_type);
rb_global_variable(&ar_pg_uuid_type);
rb_global_variable(&ar_pg_json_type);
rb_global_variable(&ar_pg_jsonb_type);
rb_global_variable(&ar_pg_array_type);
rb_global_variable(&ar_pg_date_time_type);
rb_global_variable(&ar_pg_timestamp_type);
}
2 changes: 1 addition & 1 deletion lib/panko/serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def aliases(aliases = {})
end

def method_added(method)
super(method)
super

return if @_descriptor.nil?

Expand Down

0 comments on commit 291d1dc

Please sign in to comment.