Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: помогите выбрать контейнерный класс,плз  (Прочитано 21924 раз)
0 Пользователей и 1 Гость смотрят эту тему.
ary
Гость
« : 15-04-2008 17:01 » 


--------------------------------------------------------------------------------
 
моя MFC SDI аппликация динамически отображает сигналы,получаемые с порта ,в виде разноцветного графика.

При отрисовке я запоминаю координаты каждой вершины графика и ее цвет в объект класса CMap.
По завершении измерения каждый график записывается из памяти в отдельный файл(используя сериализацию,встроенную в CMap).

ПРОБЛЕМА:Когда клиент загружает файл графика с диска ,то перед его отрисовкой всегда идет очень длинная пауза.
Как видно,медленное считывание из CMap ( lineMap.Lookup(..)) тормозит процесс.

Я хочу попробовать вместо MFC-шного CMap использовать STL::map или другой контейнер STL.
 
ВОПРОС К ЗНАТОКАМ:какой из контейнерных классов STL дает самое быстрое считывание из памяти?
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #1 : 15-04-2008 17:10 » 

Из памяти или из файла? Ты уверен, что проблема с памятью?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ary
Гость
« Ответ #2 : 15-04-2008 17:18 » 

>Из памяти или из файла?
из памяти.при сериализации содержимое файла загружается в объект CMap,откуда считываются элементы(кординаты вершины и цвет).
>Ты уверен, что проблема с памятью?
А с чем еще может быть проблема?Речь идет о тысячах вершин графика,которые нужно считать и отрисовать..
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #3 : 15-04-2008 17:56 » 

При чтении в принципе все контейнеры довольно шустрые. У них основное различие, как идет запись. Ну еше и std::list не поддерживает произвольный доступ к элементам.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 15-04-2008 18:01 » 

ary, тысяча вершин - ерунда, я делал подобное 2 года назад Улыбаюсь

не надо никакой CMap (а что это?) или "другой контейнер STL." . Пиши из памяти в файл, но потом из файла не грузи - уже ведь в памяти всё ) Ну скопируй в другое место. А файл мгновенно открывается CreateFile, если уж так надо
Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #5 : 15-04-2008 18:04 » 

Алексей1153++, Если ты изначально не знаеш количество вершин? Зачем писать свое, если уже есть готовое.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #6 : 15-04-2008 18:11 » 

ary, Кстати, а зачем ты выбрал ассоциативный массив в качестве хранилиша?
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #7 : 15-04-2008 18:43 » 

Finch, если не знаю - можно узнать Улыбаюсь Он же сказал - уже записано в файл
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #8 : 16-04-2008 04:07 » 

Хм..
почему считаешь, что поиск по симапу медленный(может хэш забыл проинициализировать?), профилировал?
чем массивы, вектора, листы и т.п. не угодили.(спасибо Finch)
в любом случае при выборе контейнера MFC vs STL выберу STL
Записан

Странно всё это....
ary
Гость
« Ответ #9 : 16-04-2008 07:14 » 

может хэш забыл проинициализировать
О!!!Точно,забыл.(:
Добавил lineMap.InitHashTable( 50000, true ) ,теперь  задержка вместо 15-20 секунд всего ок.3-4 секунд.
Но если бы ее совсем убрать,вообще было бы замечательно...

Профилировать такие вещи я не умею,к стыду своему.(Я вообще-то самоучка в MFC)
>чем массивы, вектора, листы и т.п. не угодили?(это ответ и Финчу)
когда выбирал,посмотрел здесь сравнительную таблицу MFC контейнеров:
http://msdn2.microsoft.com/en-us/library/y1z022s1.aspx

У CMap нашел 2 преимущества :
1.быстрый поиск указанного элемента(ДА,ИЗВИНЯЮСЬ ЕСЛИ НЕЧЕТКО СФОРМУЛИРОВАЛ ВОПРОС-ПОД БЫСТРЫМ ЧТЕНИЕМ ИЗ ПАМЯТИ Я ИМЕЛ ВВИДУ ИМЕННО БЫСТРЫЙ ПОИСК ЭЛЕМЕНТА)
2.возможность сериализации-т.е. не нужно самону мучаться с записью/чтением файла.

>выборе контейнера MFC vs STL выберу STL
почему?

Алексей1153++ ,>"из файла не грузи - уже ведь в памяти всё "
Речь идет о режиме просмотра ранее записанного графика,когда в памяти о нем еще ничего нет.Нужно загрузить его с файла в память,и отрисовать.Чем CreateFile лучше сериализации -не знаю.





« Последнее редактирование: 16-04-2008 08:22 от ary » Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #10 : 16-04-2008 08:29 » 

Добавил lineMap.InitHashTable( 50000, true ) ,теперь  задержка вместо 15-20 секунд всего ок.3-4 секунд.
Но если бы ее совсем убрать,вообще было бы замечательно...

Это долго. Я мерял поиск по hashmultymap получается 35 секунд(при случайном выборе ключа и 3.5 при монотонно возрастающем ключе для поиска), на 3000000 поисков по контейнеру из 6000000 элементов.

расскажи как часто ты делаешь, поиск и почему просто не итерируешься по контейнеру

У CMap нашел 2 преимущества :
1.быстрый поиск указанного элемента(ДА,ИЗВИНЯЮСЬ ЕСЛИ НЕЧЕТКО СФОРМУЛИРОВАЛ ВОПРОС-ПОД БЫСТРЫМ ЧТЕНИЕМ ИЗ ПАМЯТИ Я ИМЕЛ ВВИДУ ИМЕННО БЫСТРЫЙ ПОИСК ЭЛЕМЕНТА)
2.возможность сериализации-т.е. не нужно самону мучаться с записью/чтением файла.

Тебе точно нужен поиск? или достаточно иметь возможно просмотреть все элементы.
Самому сериализацию написать плёвое дело.

>выборе контейнера MFC vs STL выберу STL
почему?

потому, что стандарт и ИМХО интерфейсик поудобней, да и гибкость повыше будет.
Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #11 : 16-04-2008 08:45 » 

ary, оо, CreateFile в миллион с половиной раз лучше сериализации Улыбаюсь

У меня всё мгновенно открывается и записывается
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #12 : 16-04-2008 09:17 » 

Алексей1153++, боюсь ты не совсем прав, а может и я.
Как работает сериализация?
открывается файловый поток туда в некотором виде скидываются данные контейнера, закрывается поток. Всё.
Как работает десериализация?
открывается файловый поток туда в некотором виде считываются данные контейнера и наполняется контейнер, закрывается поток. Всё.

Сериализация не влияет на скорость поиска.
в случае std::map т.к. он гарантирует, что проходясь от начала до конца контейнера мы получаем отсортированные данные, то пре де сериализации мы можем использовать хинт подсказывая точку вставки в контейнер в данном случае в конец и это дополнительно увеличит скорость наполнения, но не прокатит в случае hashmap, т.к. отсутствует метод вставки с подсказкой.

Лично у меня десериализация 200000 элементов в hashmultymap каждый по 130 байт, занимала 3 секунды.

комп P4-2GHz.
Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 16-04-2008 11:55 » 

LogRus, я немного неправильно мысль высказал - я имел в виду не скорость, а удобство и обеспечение совместимости
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #14 : 16-04-2008 12:27 » 

Кстати, про "обеспечение совместимости"...
Просто сбросить объект размером sizeof() в файл? А если есть поля, которые не надо сбрасывать/перезаписывать?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 16-04-2008 15:44 » 

Ром, я всегда предусматриваю совместимость файлов, для этого записываю версию файла, и размер очередного блока данных. Если что то надо добавить (или наоборот - из старой программы загрузить новый формат) то всё легко подходит друг к другу
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #16 : 16-04-2008 17:09 » 

Леш, я немного про дркгое хотел сказать...
Например:
Код: (C++)
struct my_struct
{
    int a;
    void *ptr;
    CString str;
};
Просто сбросить в файл блок памяти нельзя. Указатель будет точно не валидным. Что будет со str?..

Еще пример:
Код: (C++)
class my_cls
{
    my_cls *next;
  public:
    int a;

    my_cls(my_cls *link);
};

my_cls::my_cls(my_cls *link)
{
    next = link;
}
Вот у нас класс с конструктором.
Код: (C++)
my_cls *p1 = new my_cls(0);
my_cls *p2 = new my_cls(p1);
// .... потом "заливаем" образ из файла в p2
Последняя операция убъет проинициализированные параметры.



Существует ли какая-нибудь более-менее универсальная методика сериализации и востановления?
« Последнее редактирование: 16-04-2008 17:11 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #17 : 17-04-2008 03:08 » 

я понял. Я в таких случаях к каждой рабочей структуре пишу функцию сохранения-восстановления, которая имеет другую структуру, годную для прямого заброса в файл
Записан

ary
Гость
« Ответ #18 : 17-04-2008 07:32 » 


Это долго. Я мерял поиск по hashmultymap получается 35 секунд(при случайном выборе ключа и 3.5 при монотонно возрастающем ключе для поиска), на 3000000 поисков по контейнеру из 6000000 элементов.

расскажи как часто ты делаешь, поиск и почему просто не итерируешься по контейнеру

В очень длинном цикле считываются данные с датчика и отображаются на графике(CEdge здесь -это класс вершины графика с двумя членами типов CPoint и COLORREF )
Каждый раз,когда отрисовывается очередной отрезок графика,его две вершины запоминаются в CMap:
Код:
void sensorClass::line(int x1, int y1, int x2, int y2,COLORREF color,int offset)
{


CPoint pparr[2];
pparr[0]=CPoint(x1,y1);
         CEdge edge1(pparr[0],color);

int count=(int)lineMap.GetCount();//запомнить 1-ю вершину отрезка
lineMap.SetAt((int)count+1,edge1);

pparr[1]=CPoint(x2,y2);
          CEdge edge2(pparr[1],color);

count=(int)lineMap.GetCount();//запомнить 2-ю вершину отрезка
lineMap.SetAt((int)count+1,edge2);

if(offset)
{
pparr[0].x=pparr[0].x-offset;               
pparr[1].x=pparr[1].x-offset;
}

dc->Polyline(pparr,2);
   

}

Ключ,по которому записывается вершина-это её последовательный номер;так же потом и считывается - в цикле for в OnPaint.
Код:
  int count=(int)sfp->lineMap.GetCount();//общее количество вершин

for (int i=1;i<=count;i=i+2)
{


    sfp->lineMap.Lookup( i, cedge ); //искать 1-ю вершину  i-го отрезка графика
    pparr[0]=cedge.point;
             pparr[0].x=pparr[0].x-offset;

    CPen pen(PS_SOLID,1,cedge.color);
    dc.SelectObject(&pen);

    sfp->lineMap.Lookup( i+1, cedge );//искать 2-ю вершину  i-го отрезка графика

    pparr[1]=cedge.point;
             pparr[1].x=pparr[1].x-offset;

    prevPoint = pparr[1];

             dc.Polyline(pparr,2);
   
}
Просто итерировать не получается,нужно чтобы вершины графика отрисовывались в той же последовательности.

« Последнее редактирование: 17-04-2008 07:39 от ary » Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #19 : 17-04-2008 08:07 » 

я понял. Я в таких случаях к каждой рабочей структуре пишу функцию сохранения-восстановления, которая имеет другую структуру, годную для прямого заброса в файл
А что-нибудь по универсальнее? Например, в базовом классе сделать методы serialize/unserialize, а в дочках только определять список сохраняемых/востанавливаемых значений.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #20 : 17-04-2008 09:13 » 

ary, вот не увидел зачем тебе мап.
берёшь вектор(или дек, или лист) и пихаешь туда данные push_back все данные векторе будут в порядке поступления(я так полагаю это правильный порядок)
т.е. пихаешь первую точку, затем вторую, затем третью
при поступлении второй точки рисуешь отрезок от первой до второй
при поступлении третий рисуешь отрезок от второй до третей

мап не нужен
поправил твой код, для вектора
Код:
void sensorClass::line(int x, int y, COLORREF color,int offset)
{
CPoint pparr[2];
pparr[0] = CPoint(x1,y1);
        CEdge edge(pparr[0],color);

long last_pos = static_cast<long>points.size() - 1; // запоминаем позицию, а не итератор т.к. push_back может приводить к инвалидации итераторов, указателей и ссылок

if(last_pos  != -1)
pparr[1] = points[last_pos ].point;

points.push_back(edge); //запомнить НОВУЮ вершину отрезка


if(last_pos  != -1) // это проверка на не первую точку, в принцепе можно реализовать во вне этого метода, добавляя первую точку без вызова sensorClass::line
{
if(offset)
{
pparr[0].x=pparr[0].x-offset;               
pparr[1].x=pparr[1].x-offset;
}


dc->Polyline(pparr,2);
}
}

typedef std::vector<CEdge>::iterator iterator;

if(points.size() < 2)
return;

iterator first_point = points.begin();
iterator second_point = ++points.begin();

for (; second_point != points.end(); first_point = second_point, ++second_point)
{

    pparr[0]=first_point->point;
            pparr[0].x=pparr[0].x-offset;

    CPen pen(PS_SOLID,1,cedge.color);
    dc.SelectObject(&pen);

    pparr[1]=second_point->point;
            pparr[1].x=pparr[1].x-offset;

            dc.Polyline(pparr,2);
}

я понял. Я в таких случаях к каждой рабочей структуре пишу функцию сохранения-восстановления, которая имеет другую структуру, годную для прямого заброса в файл
А что-нибудь по универсальнее? Например, в базовом классе сделать методы serialize/unserialize, а в дочках только определять список сохраняемых/востанавливаемых значений.

есть Улыбаюсь

уже обсуждалось
https://forum.shelek.ru/index.php/topic,13236.0.html
https://forum.shelek.ru/index.php/topic,11526.0.html

можно завести отдельную тему именно проблемам сериализации
Записан

Странно всё это....
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #21 : 17-04-2008 09:26 » 

ary, вот не увидел зачем тебе мап.
можно завести отдельную тему именно проблемам сериализации
LogRus, поддерживаю. Предлагаю ary сначала определиться, как именно нужно работать с данными - если только строго последовательно по парам, то излишние навороты только всё испортят.

Цитата: LogRus
можно завести отдельную тему именно проблемам сериализации
Вообще, тут бы даже, пожалуй, пригодилась схема "тема+статья", задача нередкая Улыбаюсь
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #22 : 17-04-2008 10:37 » 

А что-нибудь по универсальнее? Например, в базовом классе сделать методы serialize/unserialize, а в дочках только определять список сохраняемых/востанавливаемых значений.

есть Улыбаюсь

уже обсуждалось
https://forum.shelek.ru/index.php/topic,13236.0.html
https://forum.shelek.ru/index.php/topic,11526.0.html

можно завести отдельную тему именно проблемам сериализации

Ну, там лишь общие слова. Boost надо еще осваивать. Лучше было разобрать "ручной" процесс - для понимания и самообразования хорошо.

Двумя руками за новую тему. Если кто-нибудь еще и расскажет подробно, то и ногами. Улыбаюсь
« Последнее редактирование: 17-04-2008 10:38 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #23 : 17-04-2008 10:51 » 

RXL, могу выложить свои знания в небольшой статейке.
Записан

Странно всё это....
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #24 : 17-04-2008 12:19 » 

LogRus, давай! Улыбаюсь
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
ary
Гость
« Ответ #25 : 06-05-2008 08:58 » 

Всем спасибо за советы,отладил,заменил cmap на carray,все быстро отрисовывается.
« Последнее редактирование: 06-05-2008 15:24 от Джон » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines