Есть очень странная вещь, с которой я столкнулся в Android NDK.
У меня есть цикл
#include <chrono>
#include <android/log.h>
#include <vector>
while (true)
{
const int sz = 2048*2048*3;
std::vector<unsigned char> v;
{
auto startTime = std::chrono::system_clock::now();
v.resize(sz);
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now() - startTime);
__android_log_print(ANDROID_LOG_ERROR, "READFILE 1", "v.resize(%d) time : %lld\n", sz, duration.count());
}
{
auto startTime = std::chrono::system_clock::now();
v.resize(0);
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now() - startTime);
__android_log_print(ANDROID_LOG_ERROR, "READFILE 2", "v.resize(0) time : %lld\n", duration.count());
}
{
auto startTime = std::chrono::system_clock::now();
v.resize(sz);
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now() - startTime);
__android_log_print(ANDROID_LOG_ERROR, "READFILE 3", "v.resize(%d) time : %lld\n", sz, duration.count());
}
}
И есть журнал, который я получаю:
34.4171: v.resize(12582912) time : 845977
34.9682: v.resize(0) time : 550995
35.5293: v.resize(12582912) time : 561165
36.6121: v.resize(12582912) time : 530845
37.1612: v.resize(0) time : 548528
37.7183: v.resize(12582912) time : 556559
38.7811: v.resize(12582912) time : 515162
39.3312: v.resize(0) time : 550630
39.8883: v.resize(12582912) time : 556319
40.9711: v.resize(12582912) time : 530739
41.5182: v.resize(0) time : 546654
42.0733: v.resize(12582912) time : 554924
43.1321: v.resize(12582912) time : 511659
43.6802: v.resize(0) time : 547084
44.2373: v.resize(12582912) time : 557001
45.3201: v.resize(12582912) time : 530313
Итак, во-первых,
- какВы можете видеть, что я получаю 550 миллисекунд только за
resize(0)
... Это должно быть максимум 1 МИКРО секунда, а не МИЛЛИ - и, во-вторых, почему он снова получает 550 миллисекунд за
resize(size)
, если емкость вектора не изменилась?
Это очень странное поведение 2.
Вы можете взять этот фрагмент кода и проверить себя, если не верите мне :) Но просто зарегистрируйтесь на Android NDK , а не на проекте Visual Studio, потому что там он работает так, как должен.
Это действительно похоже на ошибку ...
Или что я делаю не так?
РЕДАКТИРОВАТЬ
Я проверил, что если перейти к методу resize()
, я пришел к такой петле
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
void
__vector_base<_Tp, _Allocator>::__destruct_at_end(pointer __new_last) _NOEXCEPT
{
pointer __soon_to_be_end = __end_;
while (__new_last != __soon_to_be_end)
__alloc_traits::destroy(__alloc(), _VSTD::__to_raw_pointer(--__soon_to_be_end));
__end_ = __new_last;
}
Таким образом, это означает, что есть цикл, который проходит по каждому элементу в диапазоне изменения размера и вызывает уничтожение
И нет проблем, если вы держите нетривиальные объекты, которые имеютдеструктор, НО, если вы держите в векторе (как в моем случае) int объекты, которые тривиальны и не имеют деструктора, так что ... это очень странное поведение, как вы можете вызвать деструктор из объекта, который на самом деле не 'у тебя деструктор?
Это похоже на ошибку компилятора?