Skip to content

Commit 7d643f5

Browse files
committed
string optimizations
1 parent f0203a4 commit 7d643f5

2 files changed

Lines changed: 78 additions & 32 deletions

File tree

runtime-light/stdlib/time/time-functions.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ inline array<mixed> f$getdate(int64_t timestamp = std::numeric_limits<int64_t>::
115115
result.set_value(string{"mon", 3}, t.tm_mon + 1);
116116
result.set_value(string{"year", 4}, t.tm_year + 1900);
117117
result.set_value(string{"yday", 4}, t.tm_yday);
118-
result.set_value(string{"weekday", 7}, string{weekday, static_cast<string::size_type>(std::strlen(weekday))});
119-
result.set_value(string{"month", 5}, string{month, static_cast<string::size_type>(std::strlen(month))});
118+
result.set_value(string{"weekday", 7}, string{weekday});
119+
result.set_value(string{"month", 5}, string{month});
120120
result.set_value(string{"0", 1}, timestamp);
121121

122122
return result;

runtime/datetime/timelib_wrapper.cpp

Lines changed: 76 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "runtime/datetime/timelib_wrapper.h"
22

3+
#include <string_view>
4+
35
#include "kphp/timelib/timelib.h"
46
#include "runtime-common/stdlib/time/timelib-functions.h"
57
#if ASAN_ENABLED
@@ -39,28 +41,36 @@ void set_time_value(array<mixed>& dst, const char* name, int64_t value) {
3941
}
4042

4143
array<mixed> dump_errors(const timelib_error_container& error) {
44+
static constexpr std::string_view WARNING_COUNT{"warning_count"};
45+
static constexpr std::string_view WARNINGS{"warnings"};
46+
static constexpr std::string_view ERROR_COUNT{"error_count"};
47+
static constexpr std::string_view ERRORS{"errors"};
48+
4249
array<mixed> result;
4350

4451
array<string> result_warnings;
4552
result_warnings.reserve(error.warning_count, false);
4653
for (int i = 0; i < error.warning_count; i++) {
4754
result_warnings.set_value(error.warning_messages[i].position, string(error.warning_messages[i].message));
4855
}
49-
result.set_value(string("warning_count"), error.warning_count);
50-
result.set_value(string("warnings"), result_warnings);
56+
result.set_value(string(WARNING_COUNT.data(), WARNING_COUNT.size()), error.warning_count);
57+
result.set_value(string(WARNINGS.data(), WARNINGS.size()), result_warnings);
5158

5259
array<string> result_errors;
5360
result_errors.reserve(error.error_count, false);
5461
for (int i = 0; i < error.error_count; i++) {
5562
result_errors.set_value(error.error_messages[i].position, string(error.error_messages[i].message));
5663
}
57-
result.set_value(string("error_count"), error.error_count);
58-
result.set_value(string("errors"), result_errors);
64+
result.set_value(string(ERROR_COUNT.data(), ERROR_COUNT.size()), error.error_count);
65+
result.set_value(string(ERRORS.data(), ERRORS.size()), result_errors);
5966

6067
return result;
6168
}
6269

6370
array<mixed> create_date_parse_array(timelib_time* t, timelib_error_container* error) {
71+
static constexpr std::string_view FRACTION{"fraction"};
72+
static constexpr std::string_view IS_LOCALTIME{"is_localtime"};
73+
6474
array<mixed> result;
6575

6676
// note: we're setting the result array keys in the same order as PHP does
@@ -73,56 +83,72 @@ array<mixed> create_date_parse_array(timelib_time* t, timelib_error_container* e
7383
set_time_value(result, "second", t->s);
7484

7585
if (t->us == TIMELIB_UNSET) {
76-
result.set_value(string("fraction"), false);
86+
result.set_value(string(FRACTION.data(), FRACTION.size()), false);
7787
} else {
78-
result.set_value(string("fraction"), static_cast<double>(t->us) / 1000000.0);
88+
result.set_value(string(FRACTION.data(), FRACTION.size()), static_cast<double>(t->us) / 1000000.0);
7989
}
8090

8191
result.merge_with(dump_errors(*error));
8292

83-
result.set_value(string("is_localtime"), static_cast<bool>(t->is_localtime));
93+
result.set_value(string(IS_LOCALTIME.data(), IS_LOCALTIME.size()), static_cast<bool>(t->is_localtime));
8494

8595
if (t->is_localtime) {
96+
static constexpr std::string_view IS_DST{"is_dst"};
97+
static constexpr std::string_view TZ_ABBR{"tz_abbr"};
98+
static constexpr std::string_view TZ_ID{"tz_id"};
99+
86100
set_time_value(result, "zone_type", t->zone_type);
87101
switch (t->zone_type) {
88102
case TIMELIB_ZONETYPE_OFFSET:
89103
set_time_value(result, "zone", t->z);
90-
result.set_value(string("is_dst"), static_cast<bool>(t->dst));
104+
result.set_value(string(IS_DST.data(), IS_DST.size()), static_cast<bool>(t->dst));
91105
break;
92106
case TIMELIB_ZONETYPE_ID:
93107
if (t->tz_abbr) {
94-
result.set_value(string("tz_abbr"), string(t->tz_abbr));
108+
result.set_value(string(TZ_ABBR.data(), TZ_ABBR.size()), string(t->tz_abbr));
95109
}
96110
if (t->tz_info) {
97-
result.set_value(string("tz_id"), string(t->tz_info->name));
111+
result.set_value(string(TZ_ID.data(), TZ_ID.size()), string(t->tz_info->name));
98112
}
99113
break;
100114
case TIMELIB_ZONETYPE_ABBR:
101115
set_time_value(result, "zone", t->z);
102-
result.set_value(string("is_dst"), static_cast<bool>(t->dst));
103-
result.set_value(string("tz_abbr"), string(t->tz_abbr));
116+
result.set_value(string(IS_DST.data(), IS_DST.size()), static_cast<bool>(t->dst));
117+
result.set_value(string(TZ_ABBR.data(), TZ_ABBR.size()), string(t->tz_abbr));
104118
break;
105119
}
106120
}
107121
if (t->have_relative) {
122+
static constexpr std::string_view YEAR{"year"};
123+
static constexpr std::string_view MONTH{"month"};
124+
static constexpr std::string_view DAY{"day"};
125+
static constexpr std::string_view HOUR{"hour"};
126+
static constexpr std::string_view MINUTE{"minute"};
127+
static constexpr std::string_view SECOND{"second"};
128+
static constexpr std::string_view RELATIVE{"relative"};
129+
108130
array<mixed> relative;
109-
relative.set_value(string("year"), t->relative.y);
110-
relative.set_value(string("month"), t->relative.m);
111-
relative.set_value(string("day"), t->relative.d);
112-
relative.set_value(string("hour"), t->relative.h);
113-
relative.set_value(string("minute"), t->relative.i);
114-
relative.set_value(string("second"), t->relative.s);
131+
relative.set_value(string(YEAR.data(), YEAR.size()), t->relative.y);
132+
relative.set_value(string(MONTH.data(), MONTH.size()), t->relative.m);
133+
relative.set_value(string(DAY.data(), DAY.size()), t->relative.d);
134+
relative.set_value(string(HOUR.data(), HOUR.size()), t->relative.h);
135+
relative.set_value(string(MINUTE.data(), MINUTE.size()), t->relative.i);
136+
relative.set_value(string(SECOND.data(), SECOND.size()), t->relative.s);
115137
if (t->relative.have_weekday_relative) {
116-
relative.set_value(string("weekday"), t->relative.weekday);
138+
static constexpr std::string_view WEEKDAY{"weekday"};
139+
140+
relative.set_value(string(WEEKDAY.data(), WEEKDAY.size()), t->relative.weekday);
117141
}
118142
if (t->relative.have_special_relative && (t->relative.special.type == TIMELIB_SPECIAL_WEEKDAY)) {
119-
relative.set_value(string("weekdays"), t->relative.special.amount);
143+
static constexpr std::string_view WEEKDAYS{"weekdays"};
144+
145+
relative.set_value(string(WEEKDAYS.data(), WEEKDAYS.size()), t->relative.special.amount);
120146
}
121147
if (t->relative.first_last_day_of) {
122148
string key = string(t->relative.first_last_day_of == TIMELIB_SPECIAL_FIRST_DAY_OF_MONTH ? "first_day_of_month" : "last_day_of_month");
123149
relative.set_value(key, true);
124150
}
125-
result.set_value(string("relative"), relative);
151+
result.set_value(string(RELATIVE.data(), RELATIVE.size()), relative);
126152
}
127153

128154
return result;
@@ -272,9 +298,14 @@ std::pair<timelib_time*, string> php_timelib_date_initialize(const string& tz_na
272298
update_errors_warnings(err, script_guard);
273299

274300
if (err && err->error_count) {
275-
// spit out the first library error message, at least
276301
timelib_time_dtor(t);
277-
return {nullptr, string{"Failed to parse time string "}.append(1, '(').append(time_str).append(") ").append(kphp::timelib::gen_error_msg(err))};
302+
303+
// spit out the first library error message, at least
304+
static constexpr std::string_view MESSAGE_PREFIX{"Failed to parse time string "};
305+
306+
string err_msg{MESSAGE_PREFIX.data(), MESSAGE_PREFIX.size()};
307+
err_msg.reserve_at_least(MESSAGE_PREFIX.size() + 1 + time_str.size() + 2);
308+
return {nullptr, err_msg.append(1, '(').append(time_str).append(')').append(' ').append(kphp::timelib::gen_error_msg(err))};
278309
}
279310

280311
timelib_tzinfo* tzi = nullptr;
@@ -365,7 +396,11 @@ std::pair<bool, string> php_timelib_date_modify(timelib_time* t, const string& m
365396

366397
if (err && err->error_count) {
367398
// spit out the first library error message, at least
368-
return {false, string{"Failed to parse time string "}.append(1, '(').append(modifier).append(") ").append(kphp::timelib::gen_error_msg(err))};
399+
static constexpr std::string_view MESSAGE_PREFIX{"Failed to parse time string "};
400+
401+
string err_msg{MESSAGE_PREFIX.data(), MESSAGE_PREFIX.size()};
402+
err_msg.reserve_at_least(MESSAGE_PREFIX.size() + 1 + modifier.size() + 2);
403+
return {false, err_msg.append(1, '(').append(modifier).append(')').append(' ').append(kphp::timelib::gen_error_msg(err))};
369404
}
370405

371406
std::memcpy(&t->relative, &tmp_time->relative, sizeof(timelib_rel_time));
@@ -508,7 +543,12 @@ std::pair<timelib_rel_time*, string> php_timelib_date_interval_initialize(const
508543
if (p) {
509544
timelib_rel_time_dtor(p);
510545
}
511-
return {nullptr, string{"Unknown or bad format ("}.append(format).append(1, ')')};
546+
547+
static constexpr std::string_view MESSAGE_PREFIX{"Unknown or bad format ("};
548+
549+
string err_msg{MESSAGE_PREFIX.data(), MESSAGE_PREFIX.size()};
550+
err_msg.reserve_at_least(MESSAGE_PREFIX.size() + format.size() + 1);
551+
return {nullptr, err_msg.append(format).append(1, ')')};
512552
}
513553

514554
if (p) {
@@ -521,7 +561,12 @@ std::pair<timelib_rel_time*, string> php_timelib_date_interval_initialize(const
521561
return {timelib_diff(b, e), {}};
522562
}
523563

524-
return {nullptr, string{"Failed to parse interval ("}.append(format).append(1, ')')};
564+
static constexpr std::string_view MESSAGE_PREFIX{"Failed to parse interval ("};
565+
566+
string err_msg{MESSAGE_PREFIX.data(), MESSAGE_PREFIX.size()};
567+
err_msg.reserve_at_least(MESSAGE_PREFIX.size() + format.size() + 1);
568+
569+
return {nullptr, err_msg.append(format).append(1, ')')};
525570
}
526571

527572
void php_timelib_date_interval_remove(timelib_rel_time* t) {
@@ -540,10 +585,11 @@ std::pair<timelib_rel_time*, string> php_timelib_date_interval_create_from_date_
540585
vk::final_action error_deleter{[err]() { timelib_error_container_dtor(err); }};
541586

542587
if (err->error_count > 0) {
543-
string error_msg{"Unknown or bad format ("};
544-
error_msg.append(time_str).append(1, ')').append(" at position ").append(err->error_messages[0].position);
545-
error_msg.append(" (").append(1, err->error_messages[0].character ? err->error_messages[0].character : ' ').append("): ");
546-
error_msg.append(err->error_messages[0].message);
588+
static constexpr std::string_view MESSAGE_PREFIX{"Unknown or bad format ("};
589+
590+
string error_msg{MESSAGE_PREFIX.data(), MESSAGE_PREFIX.size()};
591+
error_msg.reserve_at_least(MESSAGE_PREFIX.size() + time_str.size() + 2);
592+
error_msg.append(time_str).append(1, ')').append(1, ' ').append(kphp::timelib::gen_error_msg(err));
547593
return {nullptr, std::move(error_msg)};
548594
}
549595
return {timelib_rel_time_clone(&time->relative), {}};

0 commit comments

Comments
 (0)