XPath: Partially inline xpath_node_set_raw::push_back

Previously push_back implementation was too big to inline; now the common case
(no realloc) is small and realloc variant is explicitly marked as no-inline.

This is similar to xml_allocator::allocate_memory/allocate_memory_oob and
makes some XPath queries 5% faster.
This commit is contained in:
Arseny Kapoulkine 2014-11-07 20:29:02 +01:00
parent d854b0219d
commit 4c57d6f6fc

View file

@ -7734,26 +7734,14 @@ PUGI__NS_BEGIN
return xpath_first(_begin, _end, _type);
}
void push_back_grow(const xpath_node& node, xpath_allocator* alloc);
void push_back(const xpath_node& node, xpath_allocator* alloc)
{
if (_end == _eos)
{
size_t capacity = static_cast<size_t>(_eos - _begin);
// get new capacity (1.5x rule)
size_t new_capacity = capacity + capacity / 2 + 1;
// reallocate the old array or allocate a new one
xpath_node* data = static_cast<xpath_node*>(alloc->reallocate(_begin, capacity * sizeof(xpath_node), new_capacity * sizeof(xpath_node)));
assert(data);
// finalize
_begin = data;
_end = data + capacity;
_eos = data + new_capacity;
}
*_end++ = node;
if (_end != _eos)
*_end++ = node;
else
push_back_grow(node, alloc);
}
void append(const xpath_node* begin_, const xpath_node* end_, xpath_allocator* alloc)
@ -7810,6 +7798,26 @@ PUGI__NS_BEGIN
_type = value;
}
};
PUGI__FN_NO_INLINE void xpath_node_set_raw::push_back_grow(const xpath_node& node, xpath_allocator* alloc)
{
size_t capacity = static_cast<size_t>(_eos - _begin);
// get new capacity (1.5x rule)
size_t new_capacity = capacity + capacity / 2 + 1;
// reallocate the old array or allocate a new one
xpath_node* data = static_cast<xpath_node*>(alloc->reallocate(_begin, capacity * sizeof(xpath_node), new_capacity * sizeof(xpath_node)));
assert(data);
// finalize
_begin = data;
_end = data + capacity;
_eos = data + new_capacity;
// push
*_end++ = node;
}
PUGI__NS_END
PUGI__NS_BEGIN