XmacsLabs / lolly

lolly: A user-friendly C++ library
https://xmacslabs.github.io/lolly/
GNU General Public License v3.0
10 stars 6 forks source link

use counted pointer to hold values #326

Open jingkaimori opened 5 months ago

jingkaimori commented 5 months ago

Motivation

This pr replaces ABSTRUCT_XXX and CONCRETE_XXX with unified reference counted pointer, as a replacement of #263. Similar works can be found at https://github.com/mgubi/texmacs/tree/restructure

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

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:

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)