Concrete struct (defined by CONCRETE, *_rep and so on) is used as reference counter. For example, type T is implemented as two class: T_rep handles properties of given type, and T handles reference and counter of references to T_rep. When T is assigned, only reference is assigned with counter in/decreased.
Works
Implement an unified reference counter and corresponding managed pointer. The counter can manage reference to base class and retrieve pointer at derived class.
Provides a wrapper of memory allocator which can be regarded as a part of constructor, The wrapper method not only simplify construction of managed pointer, but also reduce boilerplate of tm_new<xxx>
Rewrite string_u16 with counted_ptr
Rewrite blackbox with counted_ptr
Rewrite tm_ostream with counted_ptr
Question
Can managed pointer point to a literal type?
Currently there is no way to get address of literal object, especially when the object is created from inside of other function, such as constructor of managed pointer. See 为什么很多std容器不能作为编译期常量? - 暮无井见铃的回答 - 知乎 for more information.
Why managed pointer holds two pointers, even though pointer of instance can be retrieved from pointer of reference counter?
Performance. Multilevel pointer and member is less effective than single cached pointer.
Are there differences between template and non-template subclass of managed pointer?
Sadly yes, there are some significant difference:
base alias type must be exploited manually to subclass of counted_ptr;
Class qualifier is required to invoke make method.
Performance
Construction is faster, but access is a bit slower:
Before
ns/op
op/s
err%
total
benchmark
6.26
159,731,650.83
0.1%
0.02
construct string_u16
18.97
52,712,186.41
1.7%
0.05
construct string_u16 with content
2.86
349,871,299.87
4.3%
0.01
equality of string
12.79
78,215,426.75
2.1%
0.03
equality of larger string
3.53
282,924,639.74
4.7%
0.01
compare string
8.44
118,545,148.01
3.3%
0.02
compare larger string
0.24
4,137,064,995.93
3.7%
0.01
slice string
0.51
1,956,419,697.31
5.7%
0.01
:wavy_dash: slice string with larger range (Unstable with ~1,595,528.7 iters. Increase minEpochIterations to e.g. 15955287)
24.68
40,524,447.25
4.0%
0.06
concat string
5.94
168,432,050.62
6.4%
0.03
:wavy_dash: append string (Unstable with ~217,087.1 iters. Increase minEpochIterations to e.g. 2170871)
After
ns/op
op/s
err%
total
benchmark
5.07
197,219,209.15
1.9%
0.01
construct string_u16
18.57
53,841,764.65
3.0%
0.05
construct string_u16 with content
6.44
155,369,720.69
3.1%
0.02
equality of string
18.83
53,117,292.73
1.8%
0.05
equality of larger string
6.73
148,633,052.83
2.9%
0.02
compare string
10.78
92,776,507.14
3.0%
0.03
compare larger string
0.24
4,123,283,367.56
4.8%
0.01
slice string
0.24
4,106,762,852.40
6.3%
0.01
:wavy_dash: slice string with larger range (Unstable with ~3,444,501.7 iters. Increase minEpochIterations to e.g. 34445017)
26.98
37,058,024.93
1.5%
0.07
concat string
8.32
120,128,145.02
6.1%
0.03
:wavy_dash: append string (Unstable with ~217,087.1 iters. Increase minEpochIterations to e.g. 2170871)
Motivation
This pr replaces
ABSTRUCT_XXX
andCONCRETE_XXX
with unified reference counted pointer, as a replacement of #263. Similar works can be found at https://github.com/mgubi/texmacs/tree/restructureConcrete struct (defined by
CONCRETE
,*_rep
and so on) is used as reference counter. For example, type T is implemented as two class: T_rep handles properties of given type, and T handles reference and counter of references to T_rep. When T is assigned, only reference is assigned with counter in/decreased.Works
tm_new<xxx>
string_u16
withcounted_ptr
blackbox
withcounted_ptr
tm_ostream
withcounted_ptr
Question
Can managed pointer point to a literal type?
Currently there is no way to get address of literal object, especially when the object is created from inside of other function, such as constructor of managed pointer. See 为什么很多std容器不能作为编译期常量? - 暮无井见铃的回答 - 知乎 for more information.
Why managed pointer holds two pointers, even though pointer of instance can be retrieved from pointer of reference counter?
Performance. Multilevel pointer and member is less effective than single cached pointer.
Are there differences between template and non-template subclass of managed pointer?
Sadly yes, there are some significant difference:
base
alias type must be exploited manually to subclass ofcounted_ptr
;make
method.Performance
Construction is faster, but access is a bit slower:
Before
construct string_u16
construct string_u16 with content
equality of string
equality of larger string
compare string
compare larger string
slice string
slice string with larger range
(Unstable with ~1,595,528.7 iters. IncreaseminEpochIterations
to e.g. 15955287)concat string
append string
(Unstable with ~217,087.1 iters. IncreaseminEpochIterations
to e.g. 2170871)After
construct string_u16
construct string_u16 with content
equality of string
equality of larger string
compare string
compare larger string
slice string
slice string with larger range
(Unstable with ~3,444,501.7 iters. IncreaseminEpochIterations
to e.g. 34445017)concat string
append string
(Unstable with ~217,087.1 iters. IncreaseminEpochIterations
to e.g. 2170871)