Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / map<char[10], char[40]> не могу откомпилировать / 17 сообщений из 17, страница 1 из 1
02.11.2013, 12:34
    #38450778
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
map<char[10], char[40]> не могу откомпилировать
Изучаю map. Надо сделать ассоциативный массив с быстрым поиском элемента по ключу. Тут map идеально подходит.
Значение в реале будет не char[40], а структура такого же размера с инфой которую надо будет постоянно менять. (Если это принципиально).
Попробовал map<string, char[40]>
пример кода 1 (ключ string)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
#include "stdafx.h"
#pragma warning( disable : 4786)
#pragma warning( disable : 4996)
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
#include <fstream>

using namespace std;

typedef struct {
	char szVal[40];
} sValue_t;

#define TEST_SIZE 1000000

int main()
{
	map <std::string, sValue_t> rows;
	char szKey[11];
	sValue_t sValue;
	std::string strKey;
	for(int i = 1; i < TEST_SIZE; i++)
	{
		sprintf(szKey, "%d", i);
		strKey = szKey;
		sprintf(sValue.szVal, "%039d", i);
		rows.insert(make_pair(strKey, sValue));
	}
	printf("Fill map %d element\n", TEST_SIZE);

	map <std::string, sValue_t>::iterator cur;
	cur = rows.find("12345");
	cout<<(*cur).first<<": "<<((*cur).second).szVal<<endl;
	Sleep(60000);
	return 0;
}


Отлично подходит. Быстро работает. НО жрет память не по-детски: данный пример забирает 110 мб на 1 млн.элементов. Полезной инфы около 47 мб (7 ключ + 40 моя инфа), остальные 63 мб получается служебная инфа. (Память диспетчером задач смотрел).

Попытался для ключа string заменить на char[10]
пример кода 2 (ключ char)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
#include "stdafx.h"
#pragma warning( disable : 4786)
#pragma warning( disable : 4996)
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
#include <fstream>

using namespace std;

typedef struct {
	char szKey[10];
} sKey_t;

typedef struct {
	char szVal[40];
} sValue_t;

struct clsCharCompare:
public                                 
binary_function<sKey_t, sKey_t, bool>
{ 
	bool operator() (const sKey_t& lhs, const sKey_t& rhs) const 
	{
		return strcmp(lhs.szKey, rhs.szKey) > 0;
	}
};

#define TEST_SIZE 1000000

int main()
{
	map <sKey_t, sValue_t, clsCharCompare> rows;
	sKey_t sKey;
	sValue_t sValue;
	for(int i = 1; i < TEST_SIZE; i++)
	{
		sprintf(sKey.szKey, "%d", i);
		sprintf(sValue.szVal, "%039d", i);
		rows.insert(make_pair(sKey, sValue));
	}
	printf("Fill map %d element\n", TEST_SIZE);

	map <std::string, sValue_t>::iterator cur;
	sKey_t sFindKey = {"12345"};
	rows.find(sFindKey); // Это работает
	
	//cur = rows.find(sFindKey); // Это не компилируется
	//cout<<((*cur).first).szKey<<": "<<((*cur).second).szVal<<endl;

	Sleep(60000);
	return 0;
}


Память расходует экономнее: занимает 80 мб из них 50 полезная инфа, 30 служебная.
Но тут начались проблемы с компиляцией:
как задать функцию сравнения ключей я разобрался (clsCharCompare) в результате чего даже заполнить получилось, но дальше какой-то взрыв мозга начинается. В инете ничего подобного не нашел.

При компиляции, на строке
Код: plaintext
1.
cur = rows.find(sFindKey);


выдает ошибку
error C2679 binary '=' : no operator found which takes a right-hand operand of type ...error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::_Tree<_Traits>::iterator' (or there is no acceptable conversion)
1> with
1> [
1> _Traits=std::_Tmap_traits<sKey_t,sValue_t,clsCharCompare,std::allocator<std::pair<const sKey_t,sValue_t>>,false>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\xtree(498): could be 'std::_Tree<_Traits>::iterator &std::_Tree<_Traits>::iterator::operator =(const std::_Tree<_Traits>::iterator &)'
1> with
1> [
1> _Traits=std::_Tmap_traits<std::string,sValue_t,std::less<std::string>,std::allocator<std::pair<const std::string,sValue_t>>,false>
1> ]
1> while trying to match the argument list '(std::_Tree<_Traits>::iterator, std::_Tree<_Traits>::iterator)'
1> with
1> [
1> _Traits=std::_Tmap_traits<std::string,sValue_t,std::less<std::string>,std::allocator<std::pair<const std::string,sValue_t>>,false>
1> ]
1> and
1> [
1> _Traits=std::_Tmap_traits<sKey_t,sValue_t,clsCharCompare,std::allocator<std::pair<const sKey_t,sValue_t>>,false>
1> ]

причем так компилируется
Код: plaintext
1.
rows.find(sFindKey);


Как понимаю - не прописано как выполнить = для моей структуры sKey_t , но как и куда это прописывать никак не могу сообразить :(
Может функция какая-то есть взамен =

С синтаксисом С++ у меня проблемы: вроде понятно в целом, разберусь, если пример похожий есть. Но на данный случай ничего похожего не нашел.

Помогите запустить второй пример или дайте ссылку на что-то похожее.
...
Рейтинг: 0 / 0
02.11.2013, 12:42
    #38450779
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
map<char[10], char[40]> не могу откомпилировать
Немного накосячил во втором примере. Вместо
Код: plaintext
1.
map <std::string, sValue_t>::iterator cur;


надо
Код: plaintext
1.
map <sKey_t, sValue_t>::iterator cur;


Но проблему мою это никак не решает.
...
Рейтинг: 0 / 0
02.11.2013, 14:35
    #38450825
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
map<char[10], char[40]> не могу откомпилировать
Dima T,

Мэп, от которого берется тип итератора, должен быть точно тем же что и для самого контейнера.
А у вас в типе итератора отсутствует компаратор.

Чтобы не извращаться, обычно пишут так:
Код: plaintext
1.
2.
3.
typedef  ... map_t;
map_t map;
map_t::iterator it = map.find(...);
...
Рейтинг: 0 / 0
02.11.2013, 15:18
    #38450847
boost
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
map<char[10], char[40]> не могу откомпилировать
Dima TНО жрет память не по-детски: данный пример забирает 110 мб на 1 млн.элементов. Полезной инфы около 47 мб (7 ключ + 40 моя инфа), остальные 63 мб получается служебная инфа. (Память диспетчером задач смотрел).


Для таких размеров лучше подходит boost::intrusive
...
Рейтинг: 0 / 0
02.11.2013, 15:20
    #38450851
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
map<char[10], char[40]> не могу откомпилировать
Dima T,

Отлично подходит. Быстро работает. НО жрет память не по-детски: данный пример забирает 110 мб на 1 млн.элементов. Полезной инфы около 47 мб (7 ключ + 40 моя инфа), остальные 63 мб получается служебная инфа. (Память диспетчером задач смотрел).

map имеет некоторые накладные расходы.
Если нужно их избежать, нужно хранить данные в сортированном векторе и искать по нему бинарным поиском.
...
Рейтинг: 0 / 0
02.11.2013, 18:22
    #38450927
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
map<char[10], char[40]> не могу откомпилировать
MasterZivmap имеет некоторые накладные расходы.
Это я понял и второй вариант меня устроит, но он не работает. Точнее map я наполнил, осталось что-то дописать, чтоб извлекать найденное. Насколько сложно это допилить?
MasterZivЕсли нужно их избежать, нужно хранить данные в сортированном векторе и искать по нему бинарным поиском.
Так и написал, только без вектора: кусок памяти и там сортированный массив структур. Бинарный поиск работает в два раза быстрее поиска map`а, но заполнение в 670 раз медленнее (0,7 сек против 470 сек.) (вставки в основном в середину), что и ожидалось, т.к. realloc() и memcpy() не быстрые.
Попробую на вектор переписать, хотя бы код будет читабельнее. Хотя возможно мой исходный вариант быстрее будет (я realloc() немного оптимизировал, сделал чтоб сразу +50% памяти добавлял).
Запустил тест вектора: заполнение вектора 1 млн. элементов со вставкой каждого в середину. Минут 20 уже молотит. Не уверен что с ним лучше будет.

Прикинул тут статистику по времени: получается что мне будет map выгоднее если каждый элемент потребуется искать менее 6000 раз. У меня по плану 100-200 в сутки в среднем. Так что мне map желательно использовать.
...
Рейтинг: 0 / 0
02.11.2013, 18:36
    #38450937
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
map<char[10], char[40]> не могу откомпилировать
boostДля таких размеров лучше подходит boost::intrusive
А какая разница с точки зрения расхода памяти, где будет храниться обвязка узлов мэпа, в узле(как в intrusive) или снаружи узла (как в std)?
...
Рейтинг: 0 / 0
02.11.2013, 18:38
    #38450938
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
map<char[10], char[40]> не могу откомпилировать
Dima TMasterZivЕсли нужно их избежать, нужно хранить данные в сортированном векторе и искать по нему бинарным поиском.
Так и написал, только без вектора: кусок памяти и там сортированный массив структур. Бинарный поиск работает в два раза быстрее поиска map`а, но заполнение в 670 раз медленнее (0,7 сек против 470 сек.) (вставки в основном в середину), что и ожидалось, т.к. realloc() и memcpy() не быстрые.
Так вы не вставляйте в середину. Дописывайте в конец, а потом все за один раз отсортируйте.
...
Рейтинг: 0 / 0
02.11.2013, 20:32
    #38450996
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
map<char[10], char[40]> не могу откомпилировать
Anatoly MoskovskyТак вы не вставляйте в середину. Дописывайте в конец, а потом все за один раз отсортируйте.
Знаю что отсортировать можно, но надо сразу в середину, т.к. элементы будут появляться/исчезать асинхронно в процессе работы.
Задачу я в итоге все равно решу, алгоритмами или деньгами (будет работать у провайдера на VDSе), но хочется алгоритмами ограничится :)

Мне кажется что я почти решил мою проблему, оптимально устраивающим меня способом, остались какие-то мелочи в допиливании второго примера.
пример кода 2 (ключ char)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
#include "stdafx.h"
#pragma warning( disable : 4786)
#pragma warning( disable : 4996)
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
#include <fstream>

using namespace std;

typedef struct {
	char szKey[10];
} sKey_t;

typedef struct {
	char szVal[40];
} sValue_t;

struct clsCharCompare:
public                                 
binary_function<sKey_t, sKey_t, bool>
{ 
	bool operator() (const sKey_t& lhs, const sKey_t& rhs) const 
	{
		return strcmp(lhs.szKey, rhs.szKey) > 0;
	}
};

#define TEST_SIZE 1000000

int main()
{
	map <sKey_t, sValue_t, clsCharCompare> rows;
	sKey_t sKey;
	sValue_t sValue;
	for(int i = 1; i < TEST_SIZE; i++)
	{
		sprintf(sKey.szKey, "%d", i);
		sprintf(sValue.szVal, "%039d", i);
		rows.insert(make_pair(sKey, sValue));
	}
	printf("Fill map %d element\n", TEST_SIZE);

	map <sKey_t, sValue_t>::iterator cur;
	sKey_t sFindKey = {"12345"};
	rows.find(sFindKey); // Это работает
	
	//cur = rows.find(sFindKey); // Это не компилируется
	//cout<<((*cur).first).szKey<<": "<<((*cur).second).szVal<<endl;

	Sleep(60000);
	return 0;
}


Или я ошибаюсь и там еще писать и писать?
...
Рейтинг: 0 / 0
02.11.2013, 20:36
    #38450997
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
map<char[10], char[40]> не могу откомпилировать
Используй хэш-таблицу вместо вектора и будет тебе счастье.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
02.11.2013, 21:28
    #38451029
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
map<char[10], char[40]> не могу откомпилировать
Dima T,

А какая проблема-то?
...
Рейтинг: 0 / 0
03.11.2013, 02:41
    #38451161
boost
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
map<char[10], char[40]> не могу откомпилировать
Anatoly MoskovskyboostДля таких размеров лучше подходит boost::intrusive
А какая разница с точки зрения расхода памяти, где будет храниться обвязка узлов мэпа, в узле(как в intrusive) или снаружи узла (как в std)?
У intrusive есть несколько преимуществ хорошо заметных на больших размерах.

IssueIntrusiveNon-intrusiveMemory managementExternalInternal through allocatorInsertion/Erasure timeFasterSlowerMemory localityBetterWorseCan hold non-copyable and non-movable objects by valueYesNoException guaranteesBetterWorseComputation of iterator from valueConstantNon-constantInsertion/erasure predictabilityHighLowMemory useMinimalMore than minimalInsert objects by value retaining polymorphic behaviorYesNo (slicing)
...
Рейтинг: 0 / 0
03.11.2013, 07:16
    #38451180
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
map<char[10], char[40]> не могу откомпилировать
boostMemory useMinimalMore than minimal
Так я и спрашиваю, для мэпа в чем конкретно разница?
Я лично ее не вижу.
...
Рейтинг: 0 / 0
03.11.2013, 08:55
    #38451184
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
map<char[10], char[40]> не могу откомпилировать
Anatoly MoskovskyDima T,

А какая проблема-то?
Такая
error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::_Tree<_Traits>::iterator' (or there is no acceptable conversion)

В первом посте написал:
Dima T Как понимаю - не прописано как выполнить = для моей структуры sKey_t , но как и куда это прописывать никак не могу сообразить :(
Может функция какая-то есть взамен =

С синтаксисом С++ у меня проблемы: вроде понятно в целом, разберусь, если пример похожий есть. Но на данный случай ничего похожего не нашел.
...
Рейтинг: 0 / 0
03.11.2013, 16:35
    #38451280
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
map<char[10], char[40]> не могу откомпилировать
Dima TAnatoly MoskovskyDima T,

А какая проблема-то?
Такая
error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::_Tree<_Traits>::iterator' (or there is no acceptable conversion)

В первом посте написал:
Dima T Как понимаю - не прописано как выполнить = для моей структуры sKey_t , но как и куда это прописывать никак не могу сообразить :(
Может функция какая-то есть взамен =

С синтаксисом С++ у меня проблемы: вроде понятно в целом, разберусь, если пример похожий есть. Но на данный случай ничего похожего не нашел.
А вы исправили то что я вам первым же сообщением написал?
Anatoly MoskovskyМэп, от которого берется тип итератора, должен быть точно тем же что и для самого контейнера.
А у вас в типе итератора отсутствует компаратор.

Чтобы не извращаться, обычно пишут так:
Код: plaintext
1.
2.
3.
typedef  ... map_t;
map_t map;
map_t::iterator it = map.find(...);
...
Рейтинг: 0 / 0
03.11.2013, 17:48
    #38451295
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
map<char[10], char[40]> не могу откомпилировать
Anatoly MoskovskyА у вас в типе итератора отсутствует компаратор.
Я тормоз :)
Сразу не понял о чем речь.
Сейчас заработало.
Спасибо.
...
Рейтинг: 0 / 0
03.11.2013, 18:16
    #38451303
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
map<char[10], char[40]> не могу откомпилировать
Замерил скорость. Летает map<char[10], char[40]>, моя поделка тормоз по сравнению с ним :)
По сравнению map<string, char[40]>:
Заполнение вдвое быстрее
Поиск в 6 раз быстрее (в 3 раза быстрее моего самодельного)

Тут лишние 30 байт на один элемент стоят того чтоб их задействовать.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / map<char[10], char[40]> не могу откомпилировать / 17 сообщений из 17, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]