mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
optimize hot code paths
This commit is contained in:
parent
bbdace8b44
commit
716a81a19f
|
@ -60,18 +60,14 @@ namespace {
|
|||
|
||||
xml::qname &qn(const std::string &namespace_, const std::string &name)
|
||||
{
|
||||
static auto &memo = *new std::unordered_map<std::string, std::unordered_map<std::string, xml::qname>>();
|
||||
|
||||
if (!memo.count(namespace_))
|
||||
{
|
||||
memo[namespace_] = std::unordered_map<std::string, xml::qname>();
|
||||
}
|
||||
using qname_map = std::unordered_map<std::string, xml::qname>;
|
||||
static auto &memo = *new std::unordered_map<std::string, qname_map>();
|
||||
|
||||
auto &ns_memo = memo[namespace_];
|
||||
|
||||
if (!ns_memo.count(name))
|
||||
if (ns_memo.find(name) == ns_memo.end())
|
||||
{
|
||||
ns_memo[name] = xml::qname(xlnt::constants::ns(namespace_), name);
|
||||
return ns_memo.emplace(name, xml::qname(xlnt::constants::ns(namespace_), name)).first->second;
|
||||
}
|
||||
|
||||
return ns_memo[name];
|
||||
|
@ -248,13 +244,24 @@ cell xlsx_consumer::read_cell()
|
|||
expect_end_element(current_element);
|
||||
}
|
||||
|
||||
expect_end_element(cell_el);
|
||||
expect_end_element(qn("spreadsheetml", "c"));
|
||||
|
||||
if (has_formula && !has_shared_formula)
|
||||
{
|
||||
cell.formula(formula_value_string);
|
||||
}
|
||||
|
||||
std::istringstream number_converter;
|
||||
number_converter.imbue(std::locale("C"));
|
||||
|
||||
auto stold = [&number_converter](const std::string &s)
|
||||
{
|
||||
number_converter.str(s);
|
||||
long double result;
|
||||
number_converter >> result;
|
||||
return result;
|
||||
};
|
||||
|
||||
if (has_value)
|
||||
{
|
||||
if (type == "str")
|
||||
|
@ -269,7 +276,7 @@ cell xlsx_consumer::read_cell()
|
|||
}
|
||||
else if (type == "s")
|
||||
{
|
||||
cell.d_->value_numeric_ = std::stold(value_string);
|
||||
cell.d_->value_numeric_ = stold(value_string);
|
||||
cell.data_type(cell::type::shared_string);
|
||||
}
|
||||
else if (type == "b") // boolean
|
||||
|
@ -278,7 +285,7 @@ cell xlsx_consumer::read_cell()
|
|||
}
|
||||
else if (type == "n") // numeric
|
||||
{
|
||||
cell.value(std::stold(value_string));
|
||||
cell.value(stold(value_string));
|
||||
}
|
||||
else if (!value_string.empty() && value_string[0] == '#')
|
||||
{
|
||||
|
@ -332,7 +339,6 @@ std::string xlsx_consumer::read_worksheet_begin(const std::string &rel_id)
|
|||
|
||||
expect_start_element(qn("spreadsheetml", "worksheet"), xml::content::complex); // CT_Worksheet
|
||||
skip_attributes({ qn("mc", "Ignorable") });
|
||||
read_namespaces();
|
||||
|
||||
while (in_element(qn("spreadsheetml", "worksheet")))
|
||||
{
|
||||
|
@ -547,6 +553,17 @@ void xlsx_consumer::read_worksheet_sheetdata()
|
|||
return;
|
||||
}
|
||||
|
||||
std::istringstream number_converter;
|
||||
number_converter.imbue(std::locale("C"));
|
||||
|
||||
auto stold = [&number_converter](const std::string &s)
|
||||
{
|
||||
number_converter.str(s);
|
||||
long double result;
|
||||
number_converter >> result;
|
||||
return result;
|
||||
};
|
||||
|
||||
while (in_element(qn("spreadsheetml", "sheetData")))
|
||||
{
|
||||
expect_start_element(qn("spreadsheetml", "row"), xml::content::complex); // CT_Row
|
||||
|
@ -648,7 +665,7 @@ void xlsx_consumer::read_worksheet_sheetdata()
|
|||
}
|
||||
else if (type == "s")
|
||||
{
|
||||
cell.d_->value_numeric_ = std::stold(value_string);
|
||||
cell.d_->value_numeric_ = stold(value_string);
|
||||
cell.data_type(cell::type::shared_string);
|
||||
}
|
||||
else if (type == "b") // boolean
|
||||
|
@ -657,7 +674,7 @@ void xlsx_consumer::read_worksheet_sheetdata()
|
|||
}
|
||||
else if (type == "n") // numeric
|
||||
{
|
||||
cell.value(std::stold(value_string));
|
||||
cell.value(stold(value_string));
|
||||
}
|
||||
else if (!value_string.empty() && value_string[0] == '#')
|
||||
{
|
||||
|
@ -1347,7 +1364,6 @@ void xlsx_consumer::read_office_document(const std::string &content_type) // CT_
|
|||
|
||||
expect_start_element(qn("workbook", "workbook"), xml::content::complex);
|
||||
skip_attribute(qn("mc", "Ignorable"));
|
||||
read_namespaces();
|
||||
|
||||
while (in_element(qn("workbook", "workbook")))
|
||||
{
|
||||
|
@ -1672,7 +1688,6 @@ void xlsx_consumer::read_stylesheet()
|
|||
|
||||
expect_start_element(qn("spreadsheetml", "styleSheet"), xml::content::complex);
|
||||
skip_attributes({qn("mc", "Ignorable")});
|
||||
read_namespaces();
|
||||
|
||||
std::vector<std::pair<style_impl, std::size_t>> styles;
|
||||
std::vector<std::pair<format_impl, std::size_t>> format_records;
|
||||
|
@ -2503,7 +2518,6 @@ void xlsx_consumer::skip_remaining_content(const xml::qname &name)
|
|||
// start by assuming we've already parsed the opening tag
|
||||
|
||||
skip_attributes();
|
||||
read_namespaces();
|
||||
read_text();
|
||||
|
||||
// continue until the closing tag is reached
|
||||
|
@ -2516,24 +2530,6 @@ void xlsx_consumer::skip_remaining_content(const xml::qname &name)
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> xlsx_consumer::read_namespaces()
|
||||
{
|
||||
std::vector<std::string> namespaces;
|
||||
|
||||
while (parser().peek() == xml::parser::event_type::start_namespace_decl)
|
||||
{
|
||||
parser().next_expect(xml::parser::event_type::start_namespace_decl);
|
||||
namespaces.push_back(parser().namespace_());
|
||||
|
||||
if (parser().peek() == xml::parser::event_type::end_namespace_decl)
|
||||
{
|
||||
parser().next_expect(xml::parser::event_type::end_namespace_decl);
|
||||
}
|
||||
}
|
||||
|
||||
return namespaces;
|
||||
}
|
||||
|
||||
bool xlsx_consumer::in_element(const xml::qname &name)
|
||||
{
|
||||
return parser().peek() != xml::parser::event_type::end_element
|
||||
|
@ -2565,12 +2561,6 @@ void xlsx_consumer::expect_start_element(const xml::qname &name, xml::content co
|
|||
void xlsx_consumer::expect_end_element(const xml::qname &name)
|
||||
{
|
||||
parser().next_expect(xml::parser::event_type::end_element, name);
|
||||
|
||||
while (parser().peek() == xml::parser::event_type::end_namespace_decl)
|
||||
{
|
||||
parser().next_expect(xml::parser::event_type::end_namespace_decl);
|
||||
}
|
||||
|
||||
stack_.pop_back();
|
||||
}
|
||||
|
||||
|
|
|
@ -357,12 +357,6 @@ private:
|
|||
/// </summary>
|
||||
bool in_element(const xml::qname &name);
|
||||
|
||||
/// <summary>
|
||||
/// Handles all start and end namespace events from the current parser
|
||||
/// and returns a vector of strings containing the URL for each namespace.
|
||||
/// </summary>
|
||||
std::vector<std::string> read_namespaces();
|
||||
|
||||
// Properties
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -352,22 +352,20 @@ void worksheet::unfreeze_panes()
|
|||
|
||||
cell worksheet::cell(const cell_reference &reference)
|
||||
{
|
||||
if (d_->cell_map_.find(reference.row()) == d_->cell_map_.end())
|
||||
{
|
||||
d_->cell_map_[reference.row()] = std::unordered_map<column_t, detail::cell_impl>();
|
||||
}
|
||||
|
||||
auto &row = d_->cell_map_[reference.row()];
|
||||
auto match = row.find(reference.column_index());
|
||||
|
||||
if (row.find(reference.column_index()) == row.end())
|
||||
if (match == row.end())
|
||||
{
|
||||
auto &impl = row[reference.column_index()] = detail::cell_impl();
|
||||
match = row.emplace(reference.column_index(), detail::cell_impl()).first;
|
||||
auto &impl = match->second;
|
||||
|
||||
impl.parent_ = d_;
|
||||
impl.column_ = reference.column_index();
|
||||
impl.row_ = reference.row();
|
||||
}
|
||||
|
||||
return xlnt::cell(&row[reference.column_index()]);
|
||||
return xlnt::cell(&match->second);
|
||||
}
|
||||
|
||||
const cell worksheet::cell(const cell_reference &reference) const
|
||||
|
|
Loading…
Reference in New Issue
Block a user