Skip to content

Commit 2e5792a

Browse files
committed
refactor: improve parameter handling and memory management across various classes
- Updated function and method signatures to use const references for string parameters, enhancing performance and clarity. - Introduced new member variables for better organization and memory management in classes such as MemberDecl and MetadataFactory. - Enhanced the handling of collections by reserving space in vectors and unordered sets to optimize memory usage. - Improved the process of adding and managing protocols, enums, and classes within the MetadataFactory, ensuring more efficient lookups and insertions. - Refactored various methods to utilize move semantics for better performance when dealing with temporary objects.
1 parent 68c2bfc commit 2e5792a

27 files changed

Lines changed: 360 additions & 345 deletions

metadata-generator/include/IR.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ class MemberDecl {
234234

235235
// Method overloads for TS emission (used to preserve superclass signatures).
236236
std::vector<MemberDecl> overloads;
237+
std::vector<std::string> overloadSignatureKeys;
237238

238239
void addOverloadFrom(const MemberDecl& member);
239240
};
@@ -248,7 +249,7 @@ class ClassDecl {
248249

249250
ClassDecl(CXCursor cursor);
250251

251-
MemberDecl* getMemberNamed(std::string& name);
252+
MemberDecl* getMemberNamed(const std::string& name);
252253

253254
void postProcessMembers();
254255

@@ -279,7 +280,7 @@ class ProtocolDecl {
279280

280281
ProtocolDecl(CXCursor cursor);
281282

282-
MemberDecl* getMemberNamed(std::string& name);
283+
MemberDecl* getMemberNamed(const std::string& name);
283284

284285
void postProcessMembers();
285286

@@ -376,10 +377,11 @@ class MetadataFactory {
376377
std::unordered_set<std::string> referencedProtocols;
377378

378379
std::unordered_set<std::string> renamedProtocols;
379-
std::unordered_set<std::string> missingClasses;
380+
std::unordered_set<std::string> missingClasses;
380381

381382
private:
382383
bool _checkAvailability = false;
384+
std::unordered_map<std::string, bool> shouldProcessCache;
383385

384386
std::unordered_map<std::string, EnumDecl> skippedEnums;
385387
std::unordered_map<std::string, StructDecl> skippedStructs;

metadata-generator/include/MetadataWriter.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -236,19 +236,22 @@ class MDSection : public std::unordered_map<MDSectionOffset, T> {
236236
size_t section_size;
237237
S serde;
238238
std::unordered_map<std::string, MDSectionOffset> stringToKey;
239+
std::vector<std::pair<MDSectionOffset, T>> orderedEntries;
239240

240241
MDSection(S serde) : section_offset(0), section_size(0), serde(serde) {}
241242

242-
inline MDSectionOffset add(T value, std::string strKey) {
243-
if (stringToKey.contains(strKey)) {
244-
return stringToKey[strKey];
243+
inline MDSectionOffset add(T value, const std::string& strKey) {
244+
auto keyIt = stringToKey.find(strKey);
245+
if (keyIt != stringToKey.end()) {
246+
return keyIt->second;
245247
}
246248
MDSectionOffset key = (MDSectionOffset)section_offset;
247249
size_t valueSize = serde.size(value);
248250
section_offset += valueSize;
249251
section_size += valueSize;
250-
this->insert(std::make_pair(key, value));
251-
stringToKey.insert(std::make_pair(strKey, key));
252+
this->emplace(key, value);
253+
orderedEntries.emplace_back(key, value);
254+
stringToKey.emplace(strKey, key);
252255
return key;
253256
}
254257
};
@@ -272,7 +275,7 @@ class MDMetadataWriter {
272275
protocols(MDProtocolSerde()), classes(MDClassSerde()),
273276
structs(MDStructSerde()), unions(MDUnionSerde()) {}
274277

275-
MDTypeInfo *getTypeInfo(TypeSpec &type);
278+
MDTypeInfo *getTypeInfo(const TypeSpec &type);
276279

277280
MDMember *memberFromDecl(MemberDecl &decl);
278281

metadata-generator/include/TSEmitter.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class TSLines {
1818
public:
1919
TSLines() {}
2020

21-
void write(std::string value);
21+
void write(const std::string& value);
2222
void newline();
2323
void enter();
2424
void exit();
@@ -48,7 +48,7 @@ class TSFile {
4848

4949
std::string toString();
5050

51-
inline void import(std::string module) { imports.insert(module); }
51+
inline void import(const std::string& module) { imports.insert(module); }
5252

5353
MetadataFactory *factory = nullptr;
5454

@@ -72,7 +72,7 @@ class TSEmitter {
7272

7373
void resolveImports(TSFile &file);
7474

75-
void ensureFile(std::string framework);
75+
TSFile& ensureFile(const std::string& framework);
7676

7777
void write();
7878

metadata-generator/include/Util.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
namespace metagen {
77

8-
inline std::string jsifySelector(std::string selector) {
8+
inline std::string jsifySelector(const std::string& selector) {
99
std::string jsifiedSelector;
10+
jsifiedSelector.reserve(selector.size());
1011
bool nextupper = false;
1112
for (auto c : selector) {
1213
if (c == ':') {
@@ -21,29 +22,31 @@ inline std::string jsifySelector(std::string selector) {
2122
return jsifiedSelector;
2223
}
2324

24-
inline std::string jsifyName(std::string name) {
25+
inline std::string jsifyName(const std::string& name) {
2526
if (name == "arguments" || name == "function" || name == "DOMException") {
2627
return name + "$";
2728
} else {
2829
return name;
2930
}
3031
}
3132

32-
inline std::vector<std::string> splitCamelCase(std::string value) {
33+
inline std::vector<std::string> splitCamelCase(const std::string& value) {
3334
std::vector<std::string> result;
35+
result.reserve(value.size() / 4 + 1);
3436

35-
std::string current = "";
37+
std::string current;
38+
current.reserve(value.size());
3639
for (auto c : value) {
3740
if (isupper(c)) {
38-
if (current != "") {
41+
if (!current.empty()) {
3942
result.emplace_back(current);
4043
}
4144
current = "";
4245
}
4346
current += c;
4447
}
4548

46-
if (current != "") {
49+
if (!current.empty()) {
4750
result.emplace_back(current);
4851
}
4952

@@ -117,7 +120,7 @@ inline bool isAvailable(CXCursor cursor) {
117120
availability == CXAvailability_Deprecated;
118121
}
119122

120-
inline bool isSelectorOwned(std::string selectorName) {
123+
inline bool isSelectorOwned(const std::string& selectorName) {
121124
return selectorName.find("copy") == 0 ||
122125
selectorName.find("mutableCopy") == 0 ||
123126
selectorName.find("new") == 0 || selectorName.find("alloc") == 0;

metadata-generator/src/IR/Category.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ void CategoryDecl::processMembers(
5959
case CXCursor_ObjCInstanceMethodDecl: {
6060
auto member = MemberDecl(cursor, cls->_classTypeParameters);
6161
member.parentClassName = cls->className;
62-
cls->members.emplace_back(member);
62+
cls->members.emplace_back(std::move(member));
6363
break;
6464
}
6565

metadata-generator/src/IR/Class.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ ClassDecl::ClassDecl(CXCursor cursor) {
9090
case CXCursor_ObjCInstanceMethodDecl: {
9191
auto member = MemberDecl(cursor, &cls->typeParameters);
9292
member.parentClassName = cls->name;
93-
cls->members.emplace_back(member);
93+
cls->members.emplace_back(std::move(member));
9494
break;
9595
}
9696
default:
@@ -102,7 +102,7 @@ ClassDecl::ClassDecl(CXCursor cursor) {
102102
this);
103103
}
104104

105-
MemberDecl* ClassDecl::getMemberNamed(std::string& name) {
105+
MemberDecl* ClassDecl::getMemberNamed(const std::string& name) {
106106
for (auto& member : members) {
107107
if (member.name == name) {
108108
return &member;
@@ -113,6 +113,7 @@ MemberDecl* ClassDecl::getMemberNamed(std::string& name) {
113113

114114
void removeDuplicateMethods(std::vector<MemberDecl>& members) {
115115
std::vector<MemberDecl> filteredMembers;
116+
filteredMembers.reserve(members.size());
116117

117118
// Remove getter methods in favor of properties
118119

@@ -154,23 +155,23 @@ void removeDuplicateMethods(std::vector<MemberDecl>& members) {
154155
filtered.insert(member.name);
155156
}
156157

157-
members = filteredMembers;
158+
members = std::move(filteredMembers);
158159
}
159160

160161
void MetadataFactory::processClassRefs() {
161162
while (!referencedClasses.empty()) {
162-
std::unordered_set<std::string> refs = referencedClasses;
163-
referencedClasses.clear();
163+
std::unordered_set<std::string> refs;
164+
refs.swap(referencedClasses);
164165

165166
for (const std::string& name : refs) {
166167
if (classes.contains(name)) {
167168
continue;
168169
}
169170

170-
if (skippedClasses.contains(name)) {
171-
ClassDecl decl = skippedClasses[name];
172-
classes[name] = decl;
173-
postProcessClass(classes[name]);
171+
auto skippedIt = skippedClasses.find(name);
172+
if (skippedIt != skippedClasses.end()) {
173+
auto [inserted, _] = classes.try_emplace(name, skippedIt->second);
174+
postProcessClass(inserted->second);
174175
} else {
175176
std::cerr << "ERROR: Unknown class " << name << std::endl;
176177
missingClasses.emplace(name);

metadata-generator/src/IR/Enum.cpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ namespace metagen {
1414
// Basically, split the name into parts (assuming camel case), and then remove
1515
// the repeating parts from the beginning and end of the name.
1616
void transformEnumMemberNames(std::vector<EnumConstDecl> &members) {
17-
std::vector<std::string> result;
1817
std::vector<std::vector<std::string>> parts;
18+
parts.reserve(members.size());
1919
size_t skip_begin = 0, skip_end = 0;
2020
std::vector<std::string> largestPart;
2121

22-
for (auto part : members) {
23-
auto split = splitCamelCase(part.name);
22+
for (const auto& member : members) {
23+
auto split = splitCamelCase(member.name);
2424
parts.emplace_back(split);
2525
if (split.size() > largestPart.size()) {
2626
largestPart = split;
@@ -30,7 +30,7 @@ void transformEnumMemberNames(std::vector<EnumConstDecl> &members) {
3030
skip_begin = skip_end = largestPart.size();
3131

3232
for (size_t i = 0; i < parts.size(); i++) {
33-
auto part = parts[i];
33+
const auto& part = parts[i];
3434
size_t skip = 0;
3535

3636
for (size_t j = 0; j < part.size(); j++) {
@@ -51,11 +51,12 @@ void transformEnumMemberNames(std::vector<EnumConstDecl> &members) {
5151

5252
skip = 0;
5353

54-
for (size_t j = part.size() - 1; j >= 0; j--) {
55-
if (j >= largestPart.size()) {
54+
for (size_t k = 0; k < part.size(); k++) {
55+
if (k >= largestPart.size()) {
5656
break;
5757
}
5858

59+
const size_t j = part.size() - 1 - k;
5960
if (part[j] == largestPart[largestPart.size() - 1 - skip]) {
6061
skip++;
6162
} else {
@@ -69,8 +70,9 @@ void transformEnumMemberNames(std::vector<EnumConstDecl> &members) {
6970
}
7071

7172
for (size_t i = 0; i < members.size(); i++) {
72-
auto part = parts[i];
73-
std::string name = "";
73+
const auto& part = parts[i];
74+
std::string name;
75+
name.reserve(members[i].name.size());
7476

7577
for (size_t j = skip_begin; j < part.size() - skip_end; j++) {
7678
name += part[j];
@@ -132,20 +134,21 @@ EnumDecl::EnumDecl(CXCursor cursor) {
132134
}
133135

134136
void MetadataFactory::processEnumRefs() {
135-
for (const std::string &ref : referencedEnums) {
137+
std::unordered_set<std::string> refs;
138+
refs.swap(referencedEnums);
139+
140+
for (const std::string &ref : refs) {
136141
if (enums.contains(ref)) {
137142
continue;
138143
}
139144

140-
if (skippedEnums.contains(ref)) {
141-
EnumDecl decl = skippedEnums[ref];
142-
enums[decl.name] = decl;
145+
auto skippedIt = skippedEnums.find(ref);
146+
if (skippedIt != skippedEnums.end()) {
147+
enums.insert_or_assign(skippedIt->second.name, skippedIt->second);
143148
} else {
144149
std::cerr << "processEnumRef: Enum " << ref << " not found" << std::endl;
145150
}
146151
}
147-
148-
referencedEnums.clear();
149152
}
150153

151154
} // namespace metagen

0 commit comments

Comments
 (0)