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.
This commit is contained in:
parent
585dcffff1
commit
bcb4fbe2eb
Notes:
git
2025-06-10 17:26:51 +00:00
83
enumerator.c
83
enumerator.c
@ -3748,6 +3748,55 @@ enumerator_s_product(int argc, VALUE *argv, VALUE klass)
|
||||
return obj;
|
||||
}
|
||||
|
||||
struct arith_seq {
|
||||
struct enumerator enumerator;
|
||||
VALUE begin;
|
||||
VALUE end;
|
||||
VALUE step;
|
||||
bool exclude_end;
|
||||
};
|
||||
|
||||
RUBY_REFERENCES(arith_seq_refs) = {
|
||||
RUBY_REF_EDGE(struct enumerator, obj),
|
||||
RUBY_REF_EDGE(struct enumerator, args),
|
||||
RUBY_REF_EDGE(struct enumerator, fib),
|
||||
RUBY_REF_EDGE(struct enumerator, dst),
|
||||
RUBY_REF_EDGE(struct enumerator, lookahead),
|
||||
RUBY_REF_EDGE(struct enumerator, feedvalue),
|
||||
RUBY_REF_EDGE(struct enumerator, stop_exc),
|
||||
RUBY_REF_EDGE(struct enumerator, size),
|
||||
RUBY_REF_EDGE(struct enumerator, procs),
|
||||
|
||||
RUBY_REF_EDGE(struct arith_seq, begin),
|
||||
RUBY_REF_EDGE(struct arith_seq, end),
|
||||
RUBY_REF_EDGE(struct arith_seq, step),
|
||||
RUBY_REF_END
|
||||
};
|
||||
|
||||
static const rb_data_type_t arith_seq_data_type = {
|
||||
"arithmetic_sequence",
|
||||
{
|
||||
RUBY_REFS_LIST_PTR(arith_seq_refs),
|
||||
RUBY_TYPED_DEFAULT_FREE,
|
||||
NULL, // Nothing allocated externally, so don't need a memsize function
|
||||
NULL,
|
||||
},
|
||||
.parent = &enumerator_data_type,
|
||||
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_DECL_MARKING | RUBY_TYPED_EMBEDDABLE
|
||||
};
|
||||
|
||||
static VALUE
|
||||
arith_seq_allocate(VALUE klass)
|
||||
{
|
||||
struct arith_seq *ptr;
|
||||
VALUE enum_obj;
|
||||
|
||||
enum_obj = TypedData_Make_Struct(klass, struct arith_seq, &arith_seq_data_type, ptr);
|
||||
ptr->enumerator.obj = Qundef;
|
||||
|
||||
return enum_obj;
|
||||
}
|
||||
|
||||
/*
|
||||
* Document-class: Enumerator::ArithmeticSequence
|
||||
*
|
||||
@ -3765,12 +3814,16 @@ rb_arith_seq_new(VALUE obj, VALUE meth, int argc, VALUE const *argv,
|
||||
rb_enumerator_size_func *size_fn,
|
||||
VALUE beg, VALUE end, VALUE step, int excl)
|
||||
{
|
||||
VALUE aseq = enumerator_init(enumerator_allocate(rb_cArithSeq),
|
||||
VALUE aseq = enumerator_init(arith_seq_allocate(rb_cArithSeq),
|
||||
obj, meth, argc, argv, size_fn, Qnil, rb_keyword_given_p());
|
||||
rb_ivar_set(aseq, id_begin, beg);
|
||||
rb_ivar_set(aseq, id_end, end);
|
||||
rb_ivar_set(aseq, id_step, step);
|
||||
rb_ivar_set(aseq, id_exclude_end, RBOOL(excl));
|
||||
struct arith_seq *ptr;
|
||||
TypedData_Get_Struct(aseq, struct arith_seq, &enumerator_data_type, ptr);
|
||||
|
||||
RB_OBJ_WRITE(aseq, &ptr->begin, beg);
|
||||
RB_OBJ_WRITE(aseq, &ptr->end, end);
|
||||
RB_OBJ_WRITE(aseq, &ptr->step, step);
|
||||
ptr->exclude_end = excl;
|
||||
|
||||
return aseq;
|
||||
}
|
||||
|
||||
@ -3783,7 +3836,9 @@ rb_arith_seq_new(VALUE obj, VALUE meth, int argc, VALUE const *argv,
|
||||
static inline VALUE
|
||||
arith_seq_begin(VALUE self)
|
||||
{
|
||||
return rb_ivar_get(self, id_begin);
|
||||
struct arith_seq *ptr;
|
||||
TypedData_Get_Struct(self, struct arith_seq, &enumerator_data_type, ptr);
|
||||
return ptr->begin;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3794,7 +3849,9 @@ arith_seq_begin(VALUE self)
|
||||
static inline VALUE
|
||||
arith_seq_end(VALUE self)
|
||||
{
|
||||
return rb_ivar_get(self, id_end);
|
||||
struct arith_seq *ptr;
|
||||
TypedData_Get_Struct(self, struct arith_seq, &enumerator_data_type, ptr);
|
||||
return ptr->end;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3806,7 +3863,9 @@ arith_seq_end(VALUE self)
|
||||
static inline VALUE
|
||||
arith_seq_step(VALUE self)
|
||||
{
|
||||
return rb_ivar_get(self, id_step);
|
||||
struct arith_seq *ptr;
|
||||
TypedData_Get_Struct(self, struct arith_seq, &enumerator_data_type, ptr);
|
||||
return ptr->step;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3817,13 +3876,17 @@ arith_seq_step(VALUE self)
|
||||
static inline VALUE
|
||||
arith_seq_exclude_end(VALUE self)
|
||||
{
|
||||
return rb_ivar_get(self, id_exclude_end);
|
||||
struct arith_seq *ptr;
|
||||
TypedData_Get_Struct(self, struct arith_seq, &enumerator_data_type, ptr);
|
||||
return RBOOL(ptr->exclude_end);
|
||||
}
|
||||
|
||||
static inline int
|
||||
arith_seq_exclude_end_p(VALUE self)
|
||||
{
|
||||
return RTEST(arith_seq_exclude_end(self));
|
||||
struct arith_seq *ptr;
|
||||
TypedData_Get_Struct(self, struct arith_seq, &enumerator_data_type, ptr);
|
||||
return ptr->exclude_end;
|
||||
}
|
||||
|
||||
int
|
||||
|
Loading…
x
Reference in New Issue
Block a user