Разное время выполнения CListCtrl::InsertItem на одном и том же количестве записей

У меня есть CListCtrl с 10000 записей, который заполняется при запуске программы, и время этой операции составляет ~ 1,3 секунды. Но если пользователь обновляет список, он заполняется примерно через 2,5–3 секунды.

В обоих случаях работает один и тот же фрагмент кода:

SetRedraw(FALSE);
SetItemCount(nCount);

// insert

SetRedraw(TRUE);

Переменная nCount равна 0 при запуске программы и 10000, когда пользователь обновляет список.

Почему время заполнения списка такое разное?

UPD: минимальный код

void CTestList::Init()
{
    InsertColumn(0, _T("Number"),   0, 50);
    InsertColumn(1, _T("Obj name"), 0, 150);
    InsertColumn(2, _T("Creator"),  0, 100);
    InsertColumn(3, _T("Editor"),   0, 100);
}

void CTestList::Reset()
{
    LVITEM item;

    item.iItem = 0;
    for (int i = 0; i < 10000; i++)
    {
        InsertRow(item, i);
        item.iItem++;
    }
}

void CTestList::InsertRow(LVITEM& item, int num)
{
    CString strNum;

    //
    item.iSubItem = 0;
    item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
    item.lParam = NULL;
    item.iImage = 0;

    strNum.Format(_T("%d"), num);
    item.pszText = (LPTSTR)(LPCTSTR)strNum;
    InsertItem(&item);

    //
    item.mask = LVIF_TEXT;
    item.iSubItem = 1;
    item.pszText = _T("Test object");
    SetItem(&item);

    //
    item.mask = LVIF_TEXT;
    item.iSubItem = 2;
    item.pszText = _T("Any one");
    SetItem(&item);

    // 
    item.iSubItem = 3;
    item.pszText = _T("Another one");
    SetItem(&item);
}

void CApp::FillList()
{
    CWaitCursor wait;

    m_list.DeleteAllItems();

    clock_t begin = clock();
    m_list.SetRedraw(FALSE);    
    m_list.SetItemCount(nCount);
    m_list.Reset();
    m_list.SetRedraw(TRUE);
    clock_t end = clock();

    double dif = static_cast<double>(end - begin) / CLOCKS_PER_SEC;

    CString str;

    str.Format(_T("Insertion time: %f"), dif);
    AfxMessageBox(str);
}

person brightside90    schedule 16.01.2015    source источник
comment
Было бы очень полезно, если бы вы предоставили минимальный воспроизводимый пример кода.   -  person csl    schedule 16.01.2015
comment
В зависимости от типа элемента, содержащегося в списке, может потребоваться сначала уничтожить все элементы, прежде чем добавлять новые.   -  person RedX    schedule 16.01.2015
comment
@csl подожди минутку, я успею   -  person brightside90    schedule 16.01.2015
comment
@RedX да, верно. Я делаю DeleteAllItems() перед SetRedraw(FALSE), но я не написал это здесь   -  person brightside90    schedule 16.01.2015
comment
Почему вы не используете виртуальный список?   -  person rrirower    schedule 16.01.2015
comment
Я бы использовал spy++, чтобы проверить, не получает ли список ненужных сообщений, также виртуальный список — лучший выбор для огромных объемов данных.   -  person marcinj    schedule 16.01.2015
comment
Виртуальный список @marcinj — ​​лучший выбор, если вы не хотите сортировать или фильтровать данные в списке.   -  person brightside90    schedule 18.01.2015
comment
@ Brightside90 это неправда, вы можете создать виртуальный список на основе массива индексов для фактических данных списка, а затем вы только сортируете индексы и фильтруете их. Это действительно супер быстро.   -  person marcinj    schedule 18.01.2015
comment
@marcinj хорошо, можешь привести пример кода?   -  person brightside90    schedule 18.01.2015


Ответы (1)


Я проверил ваш код на своей машине. Я могу воспроизвести разные тайминги, только если запускаю программу в отладчике (используя F5), но не запускаю ее без отладчика (используя Ctrl+F5 ). Так что это, похоже, не напрямую связано с вашим кодом или Windows API, а с отладчиком.

person Werner Henze    schedule 03.02.2015
comment
Я запускал этот код в отладчике и в релизе, а также заметил, что режим релиза намного быстрее, чем отладчик. Но это не решение. В обоих случаях разница во времени выполнения между первым и последующим заполнением списка значительна. - person brightside90; 04.02.2015
comment
@brightside90: Я не про отладку/выпуск говорил, а про под отладчиком и без отладчика. На моей машине не было другого времени, когда программа не запускалась без отладчика. Может быть, есть какое-то другое ограничение или какой-то другой соответствующий код, который вы не указали в своем вопросе!? - person Werner Henze; 04.02.2015
comment
Ты прав. Это было моим упущением :( Я пробовал запускать программу только в режиме отладки/релиза, и такие мысли как А как насчет того, чтобы запустить программу без использования каких-либо режимов? никогда не приходили мне в голову :( Спасибо, @Werner Henze Теперь я получаю примерно одинаковые тайминги каждый раз, когда запускаю программу и обновляю список. - person brightside90; 05.02.2015