Skip to content

Commit 01fd3f6

Browse files
committed
perf(css): reduce duplicate memory alloc for DictType
1 parent f611936 commit 01fd3f6

1 file changed

Lines changed: 98 additions & 77 deletions

File tree

src/gui/css_library.c

Lines changed: 98 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* css_library.c -- CSS library operation module.
33
*
44
* Copyright (c) 2018, Liu chao <lc-soft@live.cn> All rights reserved.
@@ -39,8 +39,10 @@
3939
#include <LCUI/gui/css_library.h>
4040
#include <LCUI/gui/css_parser.h>
4141

42-
#define MAX_NAME_LEN 256
43-
#define LEN(A) sizeof(A) / sizeof(*A)
42+
/* clang-format off */
43+
44+
#define MAX_NAME_LEN 256
45+
#define LEN(A) sizeof(A) / sizeof(*A)
4446

4547
enum SelectorRank {
4648
GENERAL_RANK = 0,
@@ -63,12 +65,12 @@ enum SelectorFinderLevel {
6365

6466
/* 样式表查找器的上下文数据结构 */
6567
typedef struct NamesFinderRec_ {
66-
int level; /**< 当前选择器层级 */
67-
int class_i; /**< 当前处理到第几个类名 */
68-
int status_i; /**< 当前处理到第几个状态名(伪类名) */
69-
int name_i; /**< 选择器名称从第几个字符开始 */
70-
char name[MAX_NAME_LEN]; /**< 选择器名称缓存 */
71-
LCUI_SelectorNode node; /**< 针对的选择器结点 */
68+
int level; /**< 当前选择器层级 */
69+
int class_i; /**< 当前处理到第几个类名 */
70+
int status_i; /**< 当前处理到第几个状态名(伪类名) */
71+
int name_i; /**< 选择器名称从第几个字符开始 */
72+
char name[MAX_NAME_LEN]; /**< 选择器名称缓存 */
73+
LCUI_SelectorNode node; /**< 针对的选择器结点 */
7274
} NamesFinderRec, *NamesFinder;
7375

7476
/** 样式链接记录组 */
@@ -89,21 +91,27 @@ typedef struct StyleNodeRec_ {
8991

9092
/** 样式链接记录 */
9193
typedef struct StyleLinkRec_ {
92-
char *selector; /**< 选择器 */
93-
StyleLinkGroup group; /**< 所属组 */
94-
LinkedList styles; /**< 作用于当前选择器的样式 */
95-
Dict *parents; /**< 父级节点 */
94+
char *selector; /**< 选择器 */
95+
StyleLinkGroup group; /**< 所属组 */
96+
LinkedList styles; /**< 作用于当前选择器的样式 */
97+
Dict *parents; /**< 父级节点 */
9698
} StyleLinkRec, *StyleLink;
9799

98100
static struct {
99101
LCUI_BOOL active;
100-
LCUI_Mutex mutex; /**< 互斥锁 */
101-
LinkedList groups; /**< 样式组列表 */
102-
Dict *cache; /**< 样式表缓存,以选择器的 hash 值索引 */
103-
Dict *names; /**< 样式属性名称表,以值的名称索引 */
104-
Dict *value_keys; /**< 样式属性值表,以值的名称索引 */
105-
Dict *value_names; /**< 样式属性值名称表,以值索引 */
106-
int count; /**< 当前记录的属性数量 */
102+
LCUI_Mutex mutex; /**< 互斥锁 */
103+
LinkedList groups; /**< 样式组列表 */
104+
Dict *cache; /**< 样式表缓存,以选择器的 hash 值索引 */
105+
Dict *names; /**< 样式属性名称表,以值的名称索引 */
106+
Dict *value_keys; /**< 样式属性值表,以值的名称索引 */
107+
Dict *value_names; /**< 样式属性值名称表,以值索引 */
108+
DictType names_dict; /**< 样式属性名称表的类型 */
109+
DictType value_keys_dict; /**< 样式属性值表的类型 */
110+
DictType value_names_dict; /**< 样式属性值名称表的类型 */
111+
DictType style_link_dict; /**< 样式链接表的类型 */
112+
DictType style_group_dict; /**< 样式组的类型 */
113+
DictType cache_dict; /**< 样式表缓存的类型 */
114+
int count; /**< 当前记录的属性数量 */
107115
} library;
108116

109117
/** 样式字符串值与标识码 */
@@ -112,6 +120,8 @@ typedef struct KeyNameGroupRec_ {
112120
char *name;
113121
} KeyNameGroupRec, *KeyNameGroup;
114122

123+
/* clang-format off */
124+
115125
static KeyNameGroupRec style_name_map[] = {
116126
{ key_visibility, "visibility" },
117127
{ key_width, "width" },
@@ -422,6 +432,7 @@ void Selector_Delete(LCUI_Selector s)
422432
LCUI_StyleSheet StyleSheet(void)
423433
{
424434
LCUI_StyleSheet ss;
435+
sizeof(LCUI_StyleRec);
425436
ss = NEW(LCUI_StyleSheetRec, 1);
426437
if (!ss) {
427438
return ss;
@@ -533,9 +544,7 @@ int StyleSheet_Replace(LCUI_StyleSheet dest, LCUI_StyleSheet src)
533544
if (s->is_valid && s->string) {
534545
free(s->wstring);
535546
}
536-
size = wcslen(src->sheet[i].wstring) + 1;
537-
s->wstring = malloc(size * sizeof(wchar_t));
538-
wcscpy(s->wstring, src->sheet[i].wstring);
547+
s->wstring = wcsdup2(src->sheet[i].wstring);
539548
break;
540549
default:
541550
*s = src->sheet[i];
@@ -1007,21 +1016,13 @@ static void DeleteStyleLink(StyleLink link)
10071016
free(link);
10081017
}
10091018

1010-
static void StyleLinkDestructor(void *privdata, void *data)
1011-
{
1012-
DeleteStyleLink(data);
1013-
}
1014-
10151019
static StyleLinkGroup CreateStyleLinkGroup(LCUI_SelectorNode snode)
10161020
{
1017-
DictType *dtype = NEW(DictType, 1);
10181021
StyleLinkGroup group = NEW(StyleLinkGroupRec, 1);
10191022
group->snode = NEW(LCUI_SelectorNodeRec, 1);
10201023
SelectorNode_Copy(group->snode, snode);
10211024
group->name = group->snode->fullname;
1022-
*dtype = DictType_StringCopyKey;
1023-
dtype->valDestructor = StyleLinkDestructor;
1024-
group->links = Dict_Create(dtype, dtype);
1025+
group->links = Dict_Create(&library.style_link_dict, NULL);
10251026
return group;
10261027
}
10271028

@@ -1040,22 +1041,22 @@ static void StyleLinkGroupDestructor(void *privdata, void *data)
10401041
DeleteStyleLinkGroup(data);
10411042
}
10421043

1044+
static void InitStyleGroupDict(void)
1045+
{
1046+
DictType *dt = &library.style_group_dict;
1047+
1048+
*dt = DictType_StringCopyKey;
1049+
dt->valDestructor = StyleLinkGroupDestructor;
1050+
}
1051+
10431052
static Dict *CreateStyleGroup(void)
10441053
{
1045-
Dict *dict;
1046-
DictType *dtype = NEW(DictType, 1);
1047-
*dtype = DictType_StringCopyKey;
1048-
dtype->valDestructor = StyleLinkGroupDestructor;
1049-
dict = Dict_Create(dtype, dtype);
1050-
return dict;
1054+
return Dict_Create(&library.style_group_dict, NULL);
10511055
}
10521056

10531057
static void DeleteStyleGroup(Dict *dict)
10541058
{
1055-
DictType *dtype;
1056-
dtype = dict->privdata;
10571059
Dict_Release(dict);
1058-
free(dtype);
10591060
}
10601061

10611062
/** 根据选择器,选中匹配的样式表 */
@@ -1372,6 +1373,7 @@ void LCUI_PrintCSSLibrary(void)
13721373
while ((entry = Dict_Next(iter))) {
13731374
DictEntry *entry_slg;
13741375
DictIterator *iter_slg;
1376+
13751377
slg = DictEntry_GetVal(entry);
13761378
iter_slg = Dict_GetIterator(slg->links);
13771379
while ((entry_slg = Dict_Next(iter_slg))) {
@@ -1473,57 +1475,73 @@ static void *IntKeyDict_KeyDup(void *privdata, const void *key)
14731475
return newkey;
14741476
}
14751477

1476-
static void LCUI_InitStylesheetCache(void)
1478+
static void InitStylesheetCache(void)
14771479
{
1478-
static DictType cachedict;
1479-
cachedict.valDup = NULL;
1480-
cachedict.keyDup = IntKeyDict_KeyDup;
1481-
cachedict.keyCompare = IntKeyDict_KeyCompare;
1482-
cachedict.hashFunction = IntKeyDict_HashFunction;
1483-
cachedict.keyDestructor = IntKeyDict_KeyDestructor;
1484-
cachedict.valDestructor = StyleSheetCacheDestructor;
1485-
cachedict.keyDestructor = IntKeyDict_KeyDestructor;
1486-
library.cache = Dict_Create(&cachedict, NULL);
1480+
DictType *dt = &library.cache_dict;
1481+
1482+
dt->valDup = NULL;
1483+
dt->keyDup = IntKeyDict_KeyDup;
1484+
dt->keyCompare = IntKeyDict_KeyCompare;
1485+
dt->hashFunction = IntKeyDict_HashFunction;
1486+
dt->keyDestructor = IntKeyDict_KeyDestructor;
1487+
dt->valDestructor = StyleSheetCacheDestructor;
1488+
dt->keyDestructor = IntKeyDict_KeyDestructor;
1489+
library.cache = Dict_Create(dt, NULL);
14871490
}
14881491

1489-
static void LCUI_DestroyStylesheetCache(void)
1492+
static void DestroyStylesheetCache(void)
14901493
{
14911494
Dict_Release(library.cache);
14921495
library.cache = NULL;
14931496
}
14941497

1495-
static void LCUI_InitStyleNameLibrary(void)
1498+
static void StyleLinkDestructor(void *privdata, void *data)
14961499
{
1497-
static DictType namedict = { 0 };
1498-
namedict.valDup = DupStyleName;
1499-
namedict.keyDup = IntKeyDict_KeyDup;
1500-
namedict.keyCompare = IntKeyDict_KeyCompare;
1501-
namedict.valDestructor = StyleNameDestructor;
1502-
namedict.hashFunction = IntKeyDict_HashFunction;
1503-
namedict.keyDestructor = IntKeyDict_KeyDestructor;
1504-
library.names = Dict_Create(&namedict, NULL);
1500+
DeleteStyleLink(data);
15051501
}
15061502

1507-
static void LCUI_DestroyStyleNameLibrary(void)
1503+
static void InitStyleLinkDict(void)
1504+
{
1505+
library.style_link_dict = DictType_StringCopyKey;
1506+
library.style_link_dict.valDestructor = StyleLinkDestructor;
1507+
}
1508+
1509+
static void InitStyleNameLibrary(void)
1510+
{
1511+
DictType *dt = &library.names_dict;
1512+
1513+
dt->valDup = DupStyleName;
1514+
dt->keyDup = IntKeyDict_KeyDup;
1515+
dt->keyCompare = IntKeyDict_KeyCompare;
1516+
dt->valDestructor = StyleNameDestructor;
1517+
dt->hashFunction = IntKeyDict_HashFunction;
1518+
dt->keyDestructor = IntKeyDict_KeyDestructor;
1519+
library.names = Dict_Create(dt, NULL);
1520+
}
1521+
1522+
static void DestroyStyleNameLibrary(void)
15081523
{
15091524
Dict_Release(library.names);
15101525
library.names = NULL;
15111526
}
15121527

1513-
static void LCUI_InitStyleValueLibrary(void)
1528+
static void InitStyleValueLibrary(void)
15141529
{
1515-
static DictType valdict, namedict = { 0 };
1516-
valdict = DictType_StringKey;
1517-
namedict.keyCompare = IntKeyDict_KeyCompare;
1518-
namedict.hashFunction = IntKeyDict_HashFunction;
1519-
valdict.valDestructor = KeyNameGroupDestructor;
1530+
DictType *keys_dt = &library.value_keys_dict;
1531+
DictType *names_dt = &library.value_names_dict;
1532+
1533+
memset(names_dt, 0, sizeof(DictType));
1534+
names_dt->keyCompare = IntKeyDict_KeyCompare;
1535+
names_dt->hashFunction = IntKeyDict_HashFunction;
1536+
*keys_dt = DictType_StringKey;
1537+
keys_dt->valDestructor = KeyNameGroupDestructor;
15201538
/* value_keys 表用于存放 key 和 name 数据 */
1521-
library.value_keys = Dict_Create(&valdict, NULL);
1539+
library.value_keys = Dict_Create(keys_dt, NULL);
15221540
/* value_names 表仅引用 value_keys 里的数据 */
1523-
library.value_names = Dict_Create(&namedict, NULL);
1541+
library.value_names = Dict_Create(names_dt, NULL);
15241542
}
15251543

1526-
static void LCUI_DestroyStyleValueLibrary(void)
1544+
static void DestroyStyleValueLibrary(void)
15271545
{
15281546
Dict_Release(library.value_names);
15291547
Dict_Release(library.value_keys);
@@ -1534,9 +1552,12 @@ static void LCUI_DestroyStyleValueLibrary(void)
15341552
void LCUI_InitCSSLibrary(void)
15351553
{
15361554
KeyNameGroup skn, skn_end;
1537-
LCUI_InitStylesheetCache();
1538-
LCUI_InitStyleNameLibrary();
1539-
LCUI_InitStyleValueLibrary();
1555+
1556+
InitStyleLinkDict();
1557+
InitStyleGroupDict();
1558+
InitStylesheetCache();
1559+
InitStyleNameLibrary();
1560+
InitStyleValueLibrary();
15401561
LCUIMutex_Init(&library.mutex);
15411562
LinkedList_Init(&library.groups);
15421563
skn_end = style_name_map + LEN(style_name_map);
@@ -1554,9 +1575,9 @@ void LCUI_InitCSSLibrary(void)
15541575
void LCUI_FreeCSSLibrary(void)
15551576
{
15561577
library.active = FALSE;
1557-
LCUI_DestroyStylesheetCache();
1558-
LCUI_DestroyStyleNameLibrary();
1559-
LCUI_DestroyStyleValueLibrary();
1578+
DestroyStylesheetCache();
1579+
DestroyStyleNameLibrary();
1580+
DestroyStyleValueLibrary();
15601581
LCUIMutex_Destroy(&library.mutex);
15611582
LinkedList_Clear(&library.groups, (FuncPtr)DeleteStyleGroup);
15621583
}

0 commit comments

Comments
 (0)