morihirok
February 23, 2020
1.4k

# rarray_value.pdf

## morihirok

February 23, 2020

## Transcript

1. Array#+ ͱ
Array#concatͷ
ϝϞϦͷ࢖͍ํͷҧ͍
@morihirok

2. ഁյతϝιουͱඇഁյతϝ
ιου
• ඇഁյతϝιου͸Ϩγʔόͷঢ়ଶʹӨڹΛٴ΅
͢
• Array#+ ͸ඇഁյతϝιου
• ഁյతϝιου͸Ϩγʔόͷঢ়ଶʹӨڹΛٴ΅͢
• Array#concat͸ഁյతϝιου

3. #+ ͱ #concat ͷҧ͍
ary1 = ['hoge', 'fuga']
ary2 = ['foo', ‘bar']
ary3 = ary1 + ary2
p ary3
=> ["hoge", "fuga", "foo", "bar"]
p ary1
=> ["hoge", “fuga"]
ary1.concat(ary2)
p ary1
=> ["hoge", "fuga", "foo", "bar"]

4. ඇഁյతϝιου͸ϝϞϦޮ཰
͕ѱ͍ͷͰ͸ʁ
ary1 = ['hoge', 'fuga']
ary2 = ['foo', ‘bar']
ary3 = ary1 + ary2
p ary3
=> ["hoge", "fuga", "foo", "bar"]
p ary1
=> ["hoge", “fuga"]
ary1.concat(ary2)
p ary1
=> ["hoge", "fuga", "foo", "bar"]
৽ͨͳ഑ྻΛੜ੒͍ͯ͠Δ

5. ͱ͍͏Θ͚Ͱௐࠪ
ary1 = ['hoge', 'fuga']
ary2 = ['foo', 'bar']
ary1.object_id
=> 180
ary1.map(&:object_id)
=> [200, 220]
ary2.object_id
=> 240
ary2.map(&:object_id)
=> [260, 280]

6. Array#concat ͷ৔߹
p ary1.object_id
=> 180
p ary1.map(&:object_id)
=> [200, 220]
p ary2.map(&:object_id)
=> [260, 280]
ary1.concat(ary2)
p ary1.object_id
=> 180
p ary1.map(&:object_id)
=> [200, 220, 260, 280]
ಉҰͷΦϒδΣΫτΛอ࣋͢Δ
഑ྻ͕׬੒

7. Array#+ ͷ৔߹
p ary1.map(&:object_id)
=> [200, 220]
p ary2.map(&:object_id)
=> [260, 280]
ary3 = ary1 + ary2
ary3.object_id
=> 300
ary3.map(&:object_id)
=> [200, 220, 260, 280]
ಉҰͷΦϒδΣΫτΛอ࣋͢Δ
഑ྻ͕׬੒
৽͍͠ΦϒδΣΫτ͕ੜ੒͞Ε
ͦΕΛอ࣋͢Δ഑ྻ͕Ͱ͖Δͱ
ࢥ͍ͬͯͨʜ

8. Arrayʹ͍ͭͯ
צҧ͍͍ͯ͠Δ͔΋͠Εͳ͍

9. Arrayͷߏ଄ମʹ͍ͭͯௐ΂Δ
struct RArray {
struct RBasic basic;
union {
struct {
long len;
union {
long capa;
#if defined(__clang__) /* <- clang++ is sane */ || \
!defined(__cplusplus) /* <- C99 is sane */ || \
(__cplusplus > 199711L) /* <- C++11 is sane */
const
#endif
VALUE shared_root;
} aux;
const VALUE *ptr;
} heap;
const VALUE ary[RARRAY_EMBED_LEN_MAX];
} as;
};

10. Arrayͷߏ଄ମʹ͍ͭͯௐ΂Δ
struct RArray {
struct RBasic basic;
union {
struct {
long len;
union {
long capa;
#if defined(__clang__) /* <- clang++ is sane */ || \
!defined(__cplusplus) /* <- C99 is sane */ || \
(__cplusplus > 199711L) /* <- C++11 is sane */
const
#endif
VALUE shared_root;
} aux;
const VALUE *ptr;
} heap;
const VALUE ary[RARRAY_EMBED_LEN_MAX];
} as;
};
ϫʔΫΞϥ΢ϯυͷΑ͏ͳͷͰ
ಡΈਐΊ͍ͯ͘ʹ͋ͨͬͯ
Ұ୴ແࢹͯ͠ΈΔ

11. Arrayͷߏ଄ମʹ͍ͭͯௐ΂Δ
struct RArray {
struct RBasic basic;
union {
struct {
long len;
union {
long capa;
const VALUE shared_root;
} aux;
const VALUE *ptr;
} heap;
const VALUE ary[RARRAY_EMBED_LEN_MAX];
} as;
};

12. Arrayͷߏ଄ମʹ͍ͭͯௐ΂Δ
struct RArray {
struct RBasic basic;
union {
struct {
long len;
union {
long capa;
const VALUE shared_root;
} aux;
const VALUE *ptr;
} heap;
const VALUE ary[RARRAY_EMBED_LEN_MAX];
} as;
};
ࣗ਎ͷܕ΍ॴଐΫϥε΍ϑϥά
શͯͷΦϒδΣΫτߏ଄ମ͕࣋ͭ
ࣗ਎ͷ഑ྻͷ਺
഑ྻͷશମαΠζ
ڞ༗ϑϥάͬΆ͍

13. Arrayͷߏ଄ମʹ͍ͭͯௐ΂Δ
struct RArray {
struct RBasic basic;
union {
struct {
long len;
union {
long capa;
const VALUE shared_root;
} aux;
const VALUE *ptr;
} heap;
const VALUE ary[RARRAY_EMBED_LEN_MAX];
} as;
};
࣮ମϝϞϦ΁ͷϙΠϯλ
ཁૉ਺͕3"33":@&.#&%@-&.@."9ҎԼͩͱ
3"SSBZߏ଄ମͷதʹ഑ྻΛ࣋ͭΒ͍͠

14. VALUEͱ͸
• ߏ଄ମ΁ͷϙΠϯλΛද͢
• ͭ·ΓRubyͷArrayͷ࣮ମϝϞϦ͸ unsigned
longͷ഑ྻ
ruby.h :102
typedef unsigned long VALUE;

15. Array#+ͷ࣮૷
VALUE
rb_ary_plus(VALUE x, VALUE y)
{
VALUE z;
long len, xlen, ylen;
y = to_ary(y);
xlen = RARRAY_LEN(x);
ylen = RARRAY_LEN(y);
len = xlen + ylen;
z = rb_ary_new2(len);
ary_memcpy(z, 0, xlen, RARRAY_CONST_PTR_TRANSIENT(x));
ary_memcpy(z, xlen, ylen, RARRAY_CONST_PTR_TRANSIENT(y));
ARY_SET_LEN(z, len);
return z;
}

16. Array#+ͷ࣮૷
VALUE
rb_ary_plus(VALUE x, VALUE y)
{
VALUE z;
long len, xlen, ylen;
y = to_ary(y);
xlen = RARRAY_LEN(x);
ylen = RARRAY_LEN(y);
len = xlen + ylen;
z = rb_ary_new2(len);
ary_memcpy(z, 0, xlen, RARRAY_CONST_PTR_TRANSIENT(x));
ary_memcpy(z, xlen, ylen, RARRAY_CONST_PTR_TRANSIENT(y));
ARY_SET_LEN(z, len);
return z;
}
৽͍͠3"SSBZߏ଄ମΛ࡞Δ
7"-6&ΛNFNDQZ͢Δ
֤ΦϒδΣΫτߏ଄ମΛίϐʔ͢ΔΘ͚Ͱ͸ͳ͍

17. Array#concatͷ࣮૷
• RArrayߏ଄ମͷheap.aux.capaΛ֬ೝ
• concatޙͷαΠζΑΓখ͔ͬͨ͞Βmalloc͠
ͨΓreallocͨ͠Γͯ͠ϝϞϦΛ֬อ͢Δ໛༷
• Ξϩέʔτ͞ΕͨϝϞϦʹVALUEΛmemcpy

18. ·ͱΊ
• ArrayͷඇഁյతϝιουͰੜ੒͞ΕΔͷ͸
unsigned intͷ഑ྻͳͷͰΊͬͪΌ௕͍Array
ͱ͔Ͱͳ͚Ε͹ϝϞϦޮ཰͸ؾʹ͠ͳͯ͘Α
ͦ͞͏
• Rubyͷ࣮૷ΛͪΐͬͱཧղͰ͖ͯΑ͔ͬͨ