Skip to content

Commit bcb4fbe

Browse files
committed
Refactor Enumerator::ArithmeticSequence to not use ivars
It's an embedded TypedData, it can much more efficiently store the references it need without using ivars.
1 parent 585dcff commit bcb4fbe

File tree

1 file changed

+73
-10
lines changed

1 file changed

+73
-10
lines changed

enumerator.c

Lines changed: 73 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3748,6 +3748,55 @@ enumerator_s_product(int argc, VALUE *argv, VALUE klass)
37483748
return obj;
37493749
}
37503750

3751+
struct arith_seq {
3752+
struct enumerator enumerator;
3753+
VALUE begin;
3754+
VALUE end;
3755+
VALUE step;
3756+
bool exclude_end;
3757+
};
3758+
3759+
RUBY_REFERENCES(arith_seq_refs) = {
3760+
RUBY_REF_EDGE(struct enumerator, obj),
3761+
RUBY_REF_EDGE(struct enumerator, args),
3762+
RUBY_REF_EDGE(struct enumerator, fib),
3763+
RUBY_REF_EDGE(struct enumerator, dst),
3764+
RUBY_REF_EDGE(struct enumerator, lookahead),
3765+
RUBY_REF_EDGE(struct enumerator, feedvalue),
3766+
RUBY_REF_EDGE(struct enumerator, stop_exc),
3767+
RUBY_REF_EDGE(struct enumerator, size),
3768+
RUBY_REF_EDGE(struct enumerator, procs),
3769+
3770+
RUBY_REF_EDGE(struct arith_seq, begin),
3771+
RUBY_REF_EDGE(struct arith_seq, end),
3772+
RUBY_REF_EDGE(struct arith_seq, step),
3773+
RUBY_REF_END
3774+
};
3775+
3776+
static const rb_data_type_t arith_seq_data_type = {
3777+
"arithmetic_sequence",
3778+
{
3779+
RUBY_REFS_LIST_PTR(arith_seq_refs),
3780+
RUBY_TYPED_DEFAULT_FREE,
3781+
NULL, // Nothing allocated externally, so don't need a memsize function
3782+
NULL,
3783+
},
3784+
.parent = &enumerator_data_type,
3785+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_DECL_MARKING | RUBY_TYPED_EMBEDDABLE
3786+
};
3787+
3788+
static VALUE
3789+
arith_seq_allocate(VALUE klass)
3790+
{
3791+
struct arith_seq *ptr;
3792+
VALUE enum_obj;
3793+
3794+
enum_obj = TypedData_Make_Struct(klass, struct arith_seq, &arith_seq_data_type, ptr);
3795+
ptr->enumerator.obj = Qundef;
3796+
3797+
return enum_obj;
3798+
}
3799+
37513800
/*
37523801
* Document-class: Enumerator::ArithmeticSequence
37533802
*
@@ -3765,12 +3814,16 @@ rb_arith_seq_new(VALUE obj, VALUE meth, int argc, VALUE const *argv,
37653814
rb_enumerator_size_func *size_fn,
37663815
VALUE beg, VALUE end, VALUE step, int excl)
37673816
{
3768-
VALUE aseq = enumerator_init(enumerator_allocate(rb_cArithSeq),
3817+
VALUE aseq = enumerator_init(arith_seq_allocate(rb_cArithSeq),
37693818
obj, meth, argc, argv, size_fn, Qnil, rb_keyword_given_p());
3770-
rb_ivar_set(aseq, id_begin, beg);
3771-
rb_ivar_set(aseq, id_end, end);
3772-
rb_ivar_set(aseq, id_step, step);
3773-
rb_ivar_set(aseq, id_exclude_end, RBOOL(excl));
3819+
struct arith_seq *ptr;
3820+
TypedData_Get_Struct(aseq, struct arith_seq, &enumerator_data_type, ptr);
3821+
3822+
RB_OBJ_WRITE(aseq, &ptr->begin, beg);
3823+
RB_OBJ_WRITE(aseq, &ptr->end, end);
3824+
RB_OBJ_WRITE(aseq, &ptr->step, step);
3825+
ptr->exclude_end = excl;
3826+
37743827
return aseq;
37753828
}
37763829

@@ -3783,7 +3836,9 @@ rb_arith_seq_new(VALUE obj, VALUE meth, int argc, VALUE const *argv,
37833836
static inline VALUE
37843837
arith_seq_begin(VALUE self)
37853838
{
3786-
return rb_ivar_get(self, id_begin);
3839+
struct arith_seq *ptr;
3840+
TypedData_Get_Struct(self, struct arith_seq, &enumerator_data_type, ptr);
3841+
return ptr->begin;
37873842
}
37883843

37893844
/*
@@ -3794,7 +3849,9 @@ arith_seq_begin(VALUE self)
37943849
static inline VALUE
37953850
arith_seq_end(VALUE self)
37963851
{
3797-
return rb_ivar_get(self, id_end);
3852+
struct arith_seq *ptr;
3853+
TypedData_Get_Struct(self, struct arith_seq, &enumerator_data_type, ptr);
3854+
return ptr->end;
37983855
}
37993856

38003857
/*
@@ -3806,7 +3863,9 @@ arith_seq_end(VALUE self)
38063863
static inline VALUE
38073864
arith_seq_step(VALUE self)
38083865
{
3809-
return rb_ivar_get(self, id_step);
3866+
struct arith_seq *ptr;
3867+
TypedData_Get_Struct(self, struct arith_seq, &enumerator_data_type, ptr);
3868+
return ptr->step;
38103869
}
38113870

38123871
/*
@@ -3817,13 +3876,17 @@ arith_seq_step(VALUE self)
38173876
static inline VALUE
38183877
arith_seq_exclude_end(VALUE self)
38193878
{
3820-
return rb_ivar_get(self, id_exclude_end);
3879+
struct arith_seq *ptr;
3880+
TypedData_Get_Struct(self, struct arith_seq, &enumerator_data_type, ptr);
3881+
return RBOOL(ptr->exclude_end);
38213882
}
38223883

38233884
static inline int
38243885
arith_seq_exclude_end_p(VALUE self)
38253886
{
3826-
return RTEST(arith_seq_exclude_end(self));
3887+
struct arith_seq *ptr;
3888+
TypedData_Get_Struct(self, struct arith_seq, &enumerator_data_type, ptr);
3889+
return ptr->exclude_end;
38273890
}
38283891

38293892
int

0 commit comments

Comments
 (0)