Skip to content

Commit 46ece6b

Browse files
authored
perf: improve ada::can_parse (#674)
* create copy of parse function, but commenting possible unnecessary code for a can_parse verification * comment unused variable * run linter * Refactor and create parse_url_impl with store_values parameter * format files * use constexpr * remove duplicated if statement
1 parent 9cd08da commit 46ece6b

File tree

6 files changed

+89
-48
lines changed

6 files changed

+89
-48
lines changed

include/ada/parser.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
#ifndef ADA_PARSER_H
66
#define ADA_PARSER_H
77

8-
#include "ada/state.h"
9-
#include "ada/encoding_type.h"
10-
#include "ada/expected.h"
11-
128
#include <optional>
139
#include <string_view>
1410

11+
#include "ada/encoding_type.h"
12+
#include "ada/expected.h"
13+
#include "ada/state.h"
14+
1515
/**
1616
* @private
1717
*/
@@ -25,7 +25,6 @@ struct url;
2525
* @brief Includes the definitions for supported parsers
2626
*/
2727
namespace ada::parser {
28-
2928
/**
3029
* Parses a url. The parameter user_input is the input to be parsed:
3130
* it should be a valid UTF-8 string. The parameter base_url is an optional
@@ -41,6 +40,14 @@ extern template url_aggregator parse_url<url_aggregator>(
4140
extern template url parse_url<url>(std::string_view user_input,
4241
const url* base_url);
4342

43+
template <typename result_type = ada::url_aggregator, bool store_values = true>
44+
result_type parse_url_impl(std::string_view user_input,
45+
const result_type* base_url = nullptr);
46+
47+
extern template url_aggregator parse_url_impl<url_aggregator>(
48+
std::string_view user_input, const url_aggregator* base_url);
49+
extern template url parse_url_impl<url>(std::string_view user_input,
50+
const url* base_url);
4451
} // namespace ada::parser
4552

4653
#endif // ADA_PARSER_H

include/ada/url.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
#ifndef ADA_URL_H
66
#define ADA_URL_H
77

8+
#include <algorithm>
9+
#include <charconv>
10+
#include <iostream>
11+
#include <optional>
12+
#include <string>
13+
#include <string_view>
14+
815
#include "ada/checkers.h"
916
#include "ada/common_defs.h"
1017
#include "ada/log.h"
@@ -14,13 +21,6 @@
1421
#include "ada/url_base.h"
1522
#include "ada/url_components.h"
1623

17-
#include <algorithm>
18-
#include <charconv>
19-
#include <iostream>
20-
#include <optional>
21-
#include <string>
22-
#include <string_view>
23-
2424
namespace ada {
2525

2626
/**
@@ -295,6 +295,11 @@ struct url : url_base {
295295
friend void ada::helpers::strip_trailing_spaces_from_opaque_path<ada::url>(
296296
ada::url &url) noexcept;
297297

298+
friend ada::url ada::parser::parse_url_impl<ada::url, true>(std::string_view,
299+
const ada::url *);
300+
friend ada::url_aggregator ada::parser::parse_url_impl<
301+
ada::url_aggregator, true>(std::string_view, const ada::url_aggregator *);
302+
298303
inline void update_unencoded_base_hash(std::string_view input);
299304
inline void update_base_hostname(std::string_view input);
300305
inline void update_base_search(std::string_view input);

include/ada/url_aggregator.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
#ifndef ADA_URL_AGGREGATOR_H
66
#define ADA_URL_AGGREGATOR_H
77

8+
#include <string>
9+
#include <string_view>
10+
811
#include "ada/common_defs.h"
912
#include "ada/url_base.h"
1013
#include "ada/url_components.h"
1114

12-
#include <string>
13-
#include <string_view>
14-
1515
namespace ada {
1616

1717
/**
@@ -205,6 +205,11 @@ struct url_aggregator : url_base {
205205
std::string_view, const ada::url_aggregator *);
206206
friend void ada::helpers::strip_trailing_spaces_from_opaque_path<
207207
ada::url_aggregator>(ada::url_aggregator &url) noexcept;
208+
friend ada::url_aggregator ada::parser::parse_url_impl<
209+
ada::url_aggregator, true>(std::string_view, const ada::url_aggregator *);
210+
friend ada::url_aggregator
211+
ada::parser::parse_url_impl<ada::url_aggregator, false>(
212+
std::string_view, const ada::url_aggregator *);
208213

209214
std::string buffer{};
210215
url_components components{};

src/checkers.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "ada/checkers.h"
2+
23
#include <algorithm>
34

45
namespace ada::checkers {

src/implementation.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ namespace ada {
1111
template <class result_type>
1212
ada_warn_unused tl::expected<result_type, ada::errors> parse(
1313
std::string_view input, const result_type* base_url) {
14-
result_type u = ada::parser::parse_url<result_type>(input, base_url);
14+
result_type u =
15+
ada::parser::parse_url_impl<result_type, true>(input, base_url);
1516
if (!u.is_valid) {
1617
return tl::unexpected(errors::generic_error);
1718
}
@@ -47,16 +48,22 @@ std::string href_from_file(std::string_view input) {
4748
}
4849

4950
bool can_parse(std::string_view input, const std::string_view* base_input) {
50-
ada::result<ada::url_aggregator> base;
51+
ada::url_aggregator base_aggregator;
5152
ada::url_aggregator* base_pointer = nullptr;
53+
5254
if (base_input != nullptr) {
53-
base = ada::parse<url_aggregator>(*base_input);
54-
if (!base) {
55+
base_aggregator = ada::parser::parse_url_impl<ada::url_aggregator, false>(
56+
*base_input, nullptr);
57+
if (!base_aggregator.is_valid) {
5558
return false;
5659
}
57-
base_pointer = &base.value();
60+
base_pointer = &base_aggregator;
5861
}
59-
return ada::parse<url_aggregator>(input, base_pointer).has_value();
62+
63+
ada::url_aggregator result =
64+
ada::parser::parse_url_impl<ada::url_aggregator, false>(input,
65+
base_pointer);
66+
return result.is_valid;
6067
}
6168

6269
ada_warn_unused std::string to_string(ada::encoding_type type) {

src/parser.cpp

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
1+
#include "ada/parser.h"
2+
3+
#include <limits>
4+
15
#include "ada.h"
2-
#include "ada/common_defs.h"
36
#include "ada/character_sets-inl.h"
7+
#include "ada/common_defs.h"
8+
#include "ada/log.h"
49
#include "ada/unicode.h"
510
#include "ada/url-inl.h"
6-
#include "ada/log.h"
7-
#include "ada/parser.h"
8-
9-
#include <limits>
1011

1112
namespace ada::parser {
1213

13-
template <class result_type>
14-
result_type parse_url(std::string_view user_input,
15-
const result_type* base_url) {
14+
template <class result_type, bool store_values>
15+
result_type parse_url_impl(std::string_view user_input,
16+
const result_type* base_url) {
1617
// We can specialize the implementation per type.
1718
// Important: result_type_is_ada_url is evaluated at *compile time*. This
1819
// means that doing if constexpr(result_type_is_ada_url) { something } else {
@@ -539,19 +540,22 @@ result_type parse_url(std::string_view user_input,
539540
}
540541
case ada::state::QUERY: {
541542
ada_log("QUERY ", helpers::substring(url_data, input_position));
542-
// Let queryPercentEncodeSet be the special-query percent-encode set if
543-
// url is special; otherwise the query percent-encode set.
544-
const uint8_t* query_percent_encode_set =
545-
url.is_special() ? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE
546-
: ada::character_sets::QUERY_PERCENT_ENCODE;
547-
548-
// Percent-encode after encoding, with encoding, buffer, and
549-
// queryPercentEncodeSet, and append the result to url's query.
550-
url.update_base_search(helpers::substring(url_data, input_position),
551-
query_percent_encode_set);
552-
ada_log("QUERY update_base_search completed ");
553-
if (fragment.has_value()) {
554-
url.update_unencoded_base_hash(*fragment);
543+
if constexpr (store_values) {
544+
// Let queryPercentEncodeSet be the special-query percent-encode set
545+
// if url is special; otherwise the query percent-encode set.
546+
const uint8_t* query_percent_encode_set =
547+
url.is_special()
548+
? ada::character_sets::SPECIAL_QUERY_PERCENT_ENCODE
549+
: ada::character_sets::QUERY_PERCENT_ENCODE;
550+
551+
// Percent-encode after encoding, with encoding, buffer, and
552+
// queryPercentEncodeSet, and append the result to url's query.
553+
url.update_base_search(helpers::substring(url_data, input_position),
554+
query_percent_encode_set);
555+
ada_log("QUERY update_base_search completed ");
556+
if (fragment.has_value()) {
557+
url.update_unencoded_base_hash(*fragment);
558+
}
555559
}
556560
return url;
557561
}
@@ -702,11 +706,13 @@ result_type parse_url(std::string_view user_input,
702706
} else {
703707
input_position = input_size + 1;
704708
}
705-
if constexpr (result_type_is_ada_url) {
706-
helpers::parse_prepared_path(view, url.type, url.path);
707-
} else {
708-
url.consume_prepared_path(view);
709-
ADA_ASSERT_TRUE(url.validate());
709+
if constexpr (store_values) {
710+
if constexpr (result_type_is_ada_url) {
711+
helpers::parse_prepared_path(view, url.type, url.path);
712+
} else {
713+
url.consume_prepared_path(view);
714+
ADA_ASSERT_TRUE(url.validate());
715+
}
710716
}
711717
break;
712718
}
@@ -906,9 +912,19 @@ result_type parse_url(std::string_view user_input,
906912
return url;
907913
}
908914

915+
template url parse_url_impl(std::string_view user_input,
916+
const url* base_url = nullptr);
917+
template url_aggregator parse_url_impl(
918+
std::string_view user_input, const url_aggregator* base_url = nullptr);
919+
920+
template <class result_type>
921+
result_type parse_url(std::string_view user_input,
922+
const result_type* base_url) {
923+
return parse_url_impl<result_type, true>(user_input, base_url);
924+
}
925+
909926
template url parse_url<url>(std::string_view user_input,
910927
const url* base_url = nullptr);
911928
template url_aggregator parse_url<url_aggregator>(
912929
std::string_view user_input, const url_aggregator* base_url = nullptr);
913-
914930
} // namespace ada::parser

0 commit comments

Comments
 (0)