![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 6 Всего: 33 |
Кто нибудь, объясните, почему:
Это что за нехороший класс такой. Его размер больше хранимой в нем строки! -------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Во втором случае у тебя массив из 4х экземпляров класса std::string.
А вообще здесь тоже народ возмущается: http://forums.msdn.microsoft.com/en-US/vcl...7-e482c4e461a7/ |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
||||
|
||||
| Mayk |
|
|||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Ужжас. Целых 32 байта. Как жить дальше?
Неужели в системных требованиях придется писать "1 mb. ram"? -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
|||
|
||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Не, не. sizeof() возвращает размер в байтах. Посмотрите файлик basic_string.h, там действительно напихали всего. |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
упс, я думал он в биты перевел...
|
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 6 Всего: 33 |
SABROG - Я всегда юзал сей класс даже не задумываясь об этом.
В данном случае мне нужно создать массив из 6 000 000 объектов, и памяти явно не хватает, ~1.3 Gb сжирает, поэтому я и решил проверить. Проверил, расстроился... Лучше бы и не зал сего -------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Ну пустые классы занимать будут тогда 183 мегабайта в твоем массиве. Я не знаю какая у тебя задача, но можно попробывать использовать массив обычных char'ов, а строки разделять \0'ми. Но это конечно, если есть возможность последовательного заполнения массива и еще надо будет написать алгоритм поиска строки по индексу. |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
не многовато-ли будет для оперативной памяти? такой массив данных нужно хранить на в файле или в БД... |
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 6 Всего: 33 |
Неа, так не пойдет... Нужно изменять значение строк. Добавлено через 2 минуты и 58 секунд Массив-то и хранится в нескольких файлах. Но для операций над ним, нужно загрузить в память. -------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Любопытный бенчмарк на сравнение Си и STL строк, не в пользу последних: http://deepencpp.blogspot.com/2007/08/stds...comparison.html
Lazin, а у меня тоже подобная ситуация возникала, из базы данных делается выборка окола 1.5 млна записей, по 20 колонок в каждой. Т.е. 30 млн. строк., которые распихваются по структурам и векторам. Сжирается вся оператива и вся виртуалка. Далее происходят операции типа парсинга этого всего дела. Объединения, конвертация из текста в числа и т.п. После того как алгоритм отработает результат пихается в Excel файл и после этого память освобождается. Теоретически можно как-то выгружать ненужные участки и подгружать новые по 10 раз, но это скажется на скорости работы программы. Т.е. либо скорость, либо память. Добавлено через 4 минуты и 4 секунды Тогда массив указателей на динамеческие строки типа char. Передал в какую-нибудь строковую функцию, она вернет новый указатель с изминенным текстом, старый удалиш и замениш новым. Правда все будет распихано по памяти неизвестно как. |
|||
|
||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
Давно уже пора переходить на x64 и не мучиться с ограничением 2гб.
-------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| vinter |
|
||||||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
если это не расчитано на машины с большим кол-вом оперативы, аля серверы. Тогда надо подумать, не ошиблись ли вы случаем с выбором алгоритма?
ничего любопытного, STL реализаций много, а значит этот бенчмарк идет лесом, и второе: по вашему за удобство ничем не надо расплачиваться?
+1 |
||||||
|
|||||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
неужели для обработки одной строки нужно знать все остальные, может как-нибудь, в несколько проходов можно все обработать? |
|||
|
||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Хотябы light-weight классы строковые сделали бы, где можно реализовать хотябы простые операции без которых невозможна работа и с обычными char массивами. |
|||
|
||||
| andrew_121 |
|
||||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 6 Всего: 33 |
Гм... Согласен! Не хотелось бы в С спускаться...но, похоже придется.
Непонял... -------------------- Удалил аккаунт. Прощайте! |
||||
|
|||||
| SABROG |
|
||||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Там если комменты почитать, то есть и обратные результаты. Пока сам не потестиш с разными реализациями не примешь правильное решение. Надо что-то с алгоритмом думать. Если программа начинает работать со свопом, то смысла тогда уже нет все держать в памяти, т.к. это равнозначно обычному чтению байтов из файла. Это сообщение отредактировал(а) SABROG - 29.7.2008, 12:44 |
||||||
|
|||||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
ОС тоже кушать хочет |
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 6 Всего: 33 |
К примеру...?
Думаю - ДА. Это алгоритм унификации слов. Т.е. есть каталог котором хранятся файлы словарей(простые .txt). Так вот при добавления нового файла, нужно проанализировать все словари на предмет повторения слов. Сами понимаете, итераций...ого-го -------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
Ты чего не понял Всегда есть два направления: память и быстродействие. В любом случае работа с данными находящимися в физической памяти(файл подкачки к которой не относится) будет всегда быстрее. Нужно найти золотую середину. Действительно ли у тебя присутствует наобходимость хранить все 6млн. объектов в памяти? -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
для процесса - 2Гб кстати можно использовать паттерн light weight хранить не массив строк, а массив объектов каждый объект хранит номер строки (или смещение) в файле если объект не используется, то он хранит необходимый минимум данных, для того что-бы он мог считать себя из файла если к объекту происходит обращение, то он считывает свои данные из памяти(так как знает откуда читать) прозрачно для клиента Вообще это дурной подход к делу, так как нужно заботиться о масштабировании, завтра тебе понадобится обработать не 6 000 000 объектов, на несколько порядков больше, и ни в какую память они не влезут, что будешь делать? Добавлено через 1 минуту и 38 секунд
ну так это просто индексация, все читать не обязательно... |
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 6 Всего: 33 |
Согласен. Нет, памяти хватает. Но как-то медлено это все происходит... Я просто кимарю на раб. месте, пока день не закончится. В данный момент в словарях 5 746 337 слов, операция над ними занимает ~13 часов на P4 Core 2 Duo 3.2Ghz? 2Gb ram DDR2-Dual. Может есть какие-то иные методы...? -------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
||||
|
||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
Да БД однозначно. Добавлено через 1 минуту и 38 секунд Надо сделать ещё одну оговорку. БД может не подойти в случае, если исходный формат, в котором будут поступать данные, всегда будет txt и от тебя это не зависит. И в случае, если данные словари достаточно часто меняются. -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
а на что время в основном тратится? |
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 6 Всего: 33 |
Абсолютно согласен. Исправлю. -------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
В случае, если структура файла меняется редко или она просто дополняется новыми словами с конца, можно хранить не слова, а хеши. Ессно проиндексировать, но здесь простое соответветствие -- хеш+позиция_в_файле
-------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
я просто подумал, если происходят частые, случайные обращения к разным записям словаря (если одна запись словаря - одна запись БД), и частые их апдэйты, то не факт что будет быстро, хотя я не работал с БД... |
|||
|
||||
| SABROG |
|
||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Может есть смысл воспользоваться одной из баз данных ? В них уже реализованы алгоритмы поиска, сравнения, индексации, экономии памяти и т.д. А вообще словари надо попросту специальным образом проиндексировать. Например создаешь файл индекса, где букве "А" соответствует стартовое смещение в файле каждого словаря и длинна участка. В итоге в память ты уже будешь загружать не все слова, а только на букву "А", далее сравниваешь сначала строки по размеру. Если длинна строк не идентична, то они уже не равны (правда не знаю, может функция сравнения строк уже так и делает. |
||||
|
|||||
| W4FhLF |
|
||||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
Тогда ещё отсортировать надо Добавлено через 6 минут и 29 секунд
Всё-таки лучше действительно посчитать один раз хеши. Возьми какую-нибудь быструю хеш-функцию, например adler32, создай массив простых структур/классов, которые бы хранили хеш слова + позицию слова в файле, можно ещё длину слова. Если основная операция сравнение слов, то здесь ты многократно выигрываешь. Мало памяти, высокая производительность как раз в случае проверки дубликатов. -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
||||
|
|||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Предварительно обработать данные - без сомнения. Создать какое-нибудь индексное B-дерево. А затем легко и приятно всё, что надо добавлять и пр. txt и прямой перебор - явно не удачное решение
|
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 6 Всего: 33 |
На std::sort(), std::unique() и далее на итерации по словам между словарями. -------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
тогда логично для этого использовать структуры данных, на которых эти операции имели бы сложность О(1) или O(ln(N)) |
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 6 Всего: 33 |
Всем Преогромное Спасибо
Приступаю к реализации. -------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| SABROG |
|
||||||||||||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Решил тоже сравнить на своей тачке скорость: gcc
msvc
А это сравнение идентичных строк удвоенной длинны (gcc):
Собирал проги без каких-либо ключей оптимизации, т.е. тупо:
Тесты проводились под Win2000SP4. Это сообщение отредактировал(а) SABROG - 29.7.2008, 18:34 |
||||||||||||||
|
|||||||||||||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
SABROG, в VS по умолчанию stl проверяет выход за границы контейнера, это отключается каким-то макросом... результат для msvc должен быть близок к результату gcc
кстати на очень длинных строках результат может каардинално измениться... |
|||
|
||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Запущу тесты на ночь на длинных строках. Завтра запощу. |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
ну не на столько-же длинных
|
|||
|
||||
| Torsten |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 174 Регистрация: 10.6.2008 Где: Pskov Репутация: 3 Всего: 7 |
Это сделано специально, чтобы когда ты увеличиваешь размер строки память не пришлось перевыделять (новую выделить, скопировать элементы, старую удалить). Так делают все stl контейнеры. Так же есть метод reserve, через который можно установить желаемый размер, но он будет установлен, только если текующий зарезирвированный размер меньше. --------------------
We have no begining, we have no end. We are infinite. |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
||||
|
||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Сегодня не судьба. Ночью в офисе вырубило электричество все результаты пропали. |
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Размер самой строки через sizeof вообще не возможно получить |
|||
|
||||
| andrew_121 |
|
||||||||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 6 Всего: 33 |
Это понятно. Но откуда взялись 32 байта Это походу 8 указателей, или что-то еще...бред... А в Лине кто-то проверял? Щас в Mingw проверю. Добавлено через 13 минут и 42 секунды Проверил. Вот результаты.
Для MSVC-2008, компилил из командной строки, без каких либо опций.
И для Mingw:
Тоже без опций. Разница на лицо. -------------------- Удалил аккаунт. Прощайте! |
||||||||
|
|||||||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
О, ещё аллокатор и итератор для начала. Может и для конца. А итератор - это уже не 4 байта...
|
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
в студии нужно компилить с таким дефайном
что-бы все было честно |
|||
|
||||
| SABROG |
|
||||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
А студия 2005 все-равно выдает 28 байт против 4х в mingw (gcc).
|
||||||
|
|||||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
ну еще-бы, он вроде-бы должен проверку итераторов отключать да, и
|
|||
|
||||
| Любитель |
|
||||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Блин, и в чём мораль? Смотрим заголовычные файлы МинГВ. Все данные строки хранятся через некий _M_dataplus, в котором есть:
И куча реинтерпрет-кастов затем. Чтобы получить, например, _Rep:
Зачем всё так сложно? Скорей всего виноват референс-каунтинг. Если хочется сравнить реально память, занимаемую строками - создаём огромное количество этих строк и смотрим, сколько памяти жрёт процесс. |
||||
|
|||||
| SABROG |
|
||||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
А я и так и так пробывал, разницы нету Последовал совету Любителя, вот код:
Создается 6 млнов экземпляров пустых классов: ![]() В итоге: mingw (gcc) - 141 896 kb msvc - 235 716 kb Это сообщение отредактировал(а) SABROG - 30.7.2008, 15:39 |
||||||
|
|||||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 6 Всего: 33 |
SABROG - Мда... Я уже поднимал тему по замене std::string из-за малого функционала.
Похоже теперь появился еще один повод искать замену std::string С каждым днем все больше радости -------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
А если хотя бы 1 символ в строку записать? Может в случае mingw для пустых строк просто не хранится никакой служебной инфы. -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
И ещё - везде надо включать оптимизацию. Иначе сравнение не объективно.
|
|||
|
||||
| SABROG |
|
||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Ну для gcc -O3 я могу прописать, на другие ключи у меня знаний не хватит. А для cl я вообще не знаю ключей оптимизации. С таким кодом я вообще получил неожиданные результаты:
gcc - 376 604kb msvc - 235 716kb Попробывал провести тест снова с пустыми классами и опять msvc продул, а с заполненными продувает gcc. Скомпилил прогу с помощью gcc с максимальной оптимизацией -O3, результат никак не изменился. Это сообщение отредактировал(а) SABROG - 30.7.2008, 16:27 |
||||
|
|||||
| Lazin |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
немного потестировал пример из блога deepencpp для разных строк
для коротких строк l1 и l2 - длины строк, конкретные значения не важны, важно отношение - больше, меньше...
для длинных
честно говоря я думал что на длинных строках результаты будут равны, но все оказалось еще интереснее... Добавлено через 44 секунды зы компилятор vs2005, ключи /O2, /Ot |
||||
|
|||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
/O1 - size /O2 - speed /Ox - full то то -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
||||
|
||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Добавил ключи /Ox и -O3 соотв, результаты не изменились никак вообще. Оптимизация вообще никак не повлияла на тесты с пустыми и заполненными классами. Т.е. осталось все прежним. Если сравнивать два теста с пустыми классами и заполненными, то можно увидеть, что размер занимаемой памяти для msvc не меняется вообще. Видимо msvc проигрывает в первом тесте из-за того, что резервирует память изначально, чего не делает gcc. Это сообщение отредактировал(а) SABROG - 30.7.2008, 16:40 |
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 6 Всего: 33 |
Гм... Я в ступоре
-------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Вот кстати еще один вариант:
Результат: msvc - 235 716kb gcc - 282 932kb А тут я решил увеличить количество строк до 90 млн.ов c непустыми классами, результат мне не очень понравился: gcc - 563 712kb msvc - 352 452 kb Это сообщение отредактировал(а) SABROG - 30.7.2008, 16:59 |
|||
|
||||
| Lycifer |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 144 Регистрация: 4.11.2007 Репутация: нет Всего: нет |
Boost::array
STL == как на ресурсы, работать быстро - гдк то слышал, хотя работать быстро не получается(во первых память не вовремя олсвобождается, а во вторых new,delete,malloc,realloc - медленнеы так как ищют дырки в памяти, то и есть свободные места) |
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Ой, а можно по-русски? Добавлено через 21 секунду Да, и кстати boost::array - это для массивов постоянного размера. |
|||
|
||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
А вот в подтверждение моих слов результаты метода max_size(), который возвращает максимальное количество символов, которое может содержать экземпляр класса std::string:
gcc - 1073741820 msvc - 4294967294 Т.е. все-таки msvc хоть и имеет размер класса 28 байт, но он резервирует много памяти для новой строки о чем говорит функция capacity(), которая возвращает 15 байт для msvc и 0 байт для gcc. Это сообщение отредактировал(а) SABROG - 30.7.2008, 17:19 |
|||
|
||||
| just_geek |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 309 Регистрация: 13.12.2007 Репутация: 2 Всего: 10 |
Еще ради интереса stlport бы сравнили на обоих компиляторах
|
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
мне вот интересно к чему эти тесты? если бы С строки оказались быстркее, вы бы отказались от string? иЛи из-за того, что msvc дает меньший размер все бросят gcc? по моему это пустая трата времени...
|
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
А к чему любые подобные тесты?
|
|||
|
||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Ага, а потом начнется, а вот еще и для watcom сравните и для icc и для bcc. А потом на разных платформах, операционных системах. А потом версии библиотек, стабильные/не стабильные. А потом еще и с разными ключами собранные библиотеки. А потом скажут, что сравниваете не верно, код должен быть другой. |
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 6 Всего: 33 |
А у меня stlport не собирается для Студии. Вот что сообщает:
Какие мысли? -------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| Torsten |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 174 Регистрация: 10.6.2008 Где: Pskov Репутация: 3 Всего: 7 |
Вы на stlport тестируйте, там честнее будет для всех компиляторов, т.к. у студии собственная stl.
--------------------
We have no begining, we have no end. We are infinite. |
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 6 Всего: 33 |
Вот я и попытался... -------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| SABROG |
|
||||||||||||||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Народ, а че за фигня. Прописал пути:
Пытаюсь скомпилить так:
Получаю:
Меняю на
Получаю
Меняю на:
Опять не компилится. Меняю на полный путь:
Компилиться. Почему линкер не видит ни переменную окружения LIB, ни косвенный путь через -L./LIB/ (даже -L../LIB пробывал с вариациями) ? --- Ага, это спасает отца русской демократии:
Это сообщение отредактировал(а) SABROG - 30.7.2008, 23:51 |
||||||||||||||||
|
|||||||||||||||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Вроде бы собрал STLPort для обоих компиляторов, а размеры классов почему-то не изменились также как и количество занимаемой памяти. Даже как в мануале прописал инклюд первым, видимо компилеры все-таки родной STL включают. Пол третьего ночи, сил уже нету...
|
|||
|
||||
| Mayk |
|
|||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Попробуй в STLPort'овском string'е прописать #error hello world. если сообщение ошибке не вылетит - значит stl port не подключен. если вылетит - подключен -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
|||
|
||||
| SABROG |
|
||||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Прописал этот error в файле "string.h" STLPort'a, снес переменную окружения INCLUDE, прописал в переменной окружения PATH путь с инклюдами STLPort'a в самом начале. Не помогает, все-равно mingw берет старый и все нормально компилит. --- Похоже при компиляции каждый раз нужно задавать непосредственные пути. Так error выдает, что говорит о том, что все-таки STLPort увиделся:
--- Фух, собрал таки наконец. Итак 6 млн.ов классов std::string (STLPort) занимают в памяти: msvc - 189 132kb (Родной STL - 235 716kb) mingw - 188 912 kb (Родной STL - 141 896kb) Пустой класс имеет размер 24 байта для обоих компиляторов. 6 млн.ов строк "hello, worldhello, worldhello, worldhello, worldhello, worldhello, worldhello, worldhello, worldhello, worldhello, worldhello, worldhello, worldhello, world" отнимают приблизительно 1 гиг и 200 мегов памяти и при этом разница между компиляторами не была больше 400кб. Это сообщение отредактировал(а) SABROG - 31.7.2008, 08:55 |
||||
|
|||||
| andrew_121 |
|
||||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 6 Всего: 33 |
SABROG - Вот ты упертый
Я вот поразмыслил. В моем представлении строковый класс должен содержать что-то вроде:
или
И это 12 байт. А на* еще 12 байт, и для чего их использовать...хз... -------------------- Удалил аккаунт. Прощайте! |
||||
|
|||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Дык я же писал, что у msvc 15 байт в резерве на строку. Т.е. по сути пустой экземпляр класса std::string это готовая строка размером в 15 байт, поэтому нет никакой разницы между пустым классом и заполненным, если строка меньше 15 символов. Делалось это, по видимому, для ускорения работы программы, чтобы не приходилось дополнительно выделять память под каждую строку в зависимости от длинны строки. |
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
SABROG, строка хранится в памяти непрерывно. Это вообщем-то факт (чтобы нормально рабоали c_str и data). Поэтому в классе должен быть только указатель на строку. Никак не сама строка.
|
|||
|
||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Я писал раньше, что метод capacity() возвращет количество символов, которое может содержать строка изначально. Эксперимент показал, что размеры занимаемой памяти никак не менялся, если я создавал 6 млн.ов пустых строк, или 6 млн.ов строк длинной меньше 15 символов (hello, world). |
|||
|
||||
| Mayk |
|
|||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Скажи это разработчикам STLport и STL в MS. А то они совсем идиоты. Ещё расскажи им что хранить в классе длину строки не надо. Ибо "только указатель" это наше всё. -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
И? То, что во многих реализациях стл память резервируется заранее - это очевидно. Только к sizeof-у сабжевому это не имеет никакого отношения
|
|||
|
||||
| Mayk |
|
|||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
плин не получилось впереёд SABROG'а ответить
тьфу блин не склеилось
И где же она резервируется как не внутри класса? Берется из эфира? Это сообщение отредактировал(а) Mayk - 31.7.2008, 13:47 -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
|||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
в классе хранится указатель на выделенную в куче память. Причем тут объект класса?
и что? это размер выделенной памяти, каким образом это должно показать, что память выделена внутри объекта? |
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Mayk!
Добавлено через 1 минуту и 42 секунды Резервируется, короче, она никак не внутри класса. Ибо размер класса статичен, строки - нет. А очень желательно хранить строку непрерывно (иначе - проблем больше будет). Что касается размера буфера, размера строки, аллокаторов, итераторов и пр. - да, это хранится в самом классе. Не только указатель, но никак ни сама строка. Добавлено через 2 минуты и 36 секунд К слову - Dinkumware STL. Платно доступна, кстати, для гцц |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
ну и понаписали вы тут, мне кажется автору топика вовсе не обязательно хранить строки, достаточно хранить в памяти хэш, 32 бита и никакой тебе динамической памяти, указателей и прочего
|
|||
|
||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Какие алгоритмы могут дать хэш размером в 32 бита ? Я правильно понимаю "хэш" в данном контексте это уникальное значение, которое берется путем математических манипуляций с уникальной строкой. Т.е. если была строка "Hello, World" и я поменяю W на прописную w, то хэш уже будет другой. И хэш будет мне гарантировать, что в базе не появится строка с подобных хешем. Когда я подобное искал, то не нашел алгоритмов с хэшами меньше 128 бит и то они не гарантировали уникальности. В итоге пришел к выводу, что экономнее хранить строки как есть, т.к. хэши даже для однобайтовых строк слишком длинные. |
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Хеш - не может быть абсолютно уникальным
Это сообщение отредактировал(а) Любитель - 31.7.2008, 15:03 |
|||
|
||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
http://en.wikipedia.org/wiki/Adler-32 Для нескольких миллионов слов пойдёт.
Как они могут гарантировать уникальность? Сколько всего состояний может принять последовательность 128 бит? 2^128. А сколько всего состояний может принять последовательность, например, из 256 бит? Ясно, что 2^256 >> 2^128 и что меньшая последовательность в прицнипе не сможет хранить все состояния первой. Тут вопрос вероятности, а в нормальных хеш-функциях они очень малы, поэтому ими пренебрегают. Это сообщение отредактировал(а) W4FhLF - 31.7.2008, 15:06 -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
||||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
boost::hash пишет хэш в size_t, 2^32 = 4 294 967 296 количество слов = 6 000 000 так что коллизии маловероятны... |
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 6 Всего: 33 |
Не согласен. Если в цикле нужно проверять размер одной и той же строки, то это расходы на strlen(). Плюс, необходимо знать размер вместимости строки, и предварительно выделять с запасом, чтоб избежать постоянного перевыделения памяти. имхо. -------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| UnrealMan |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
Сделано специально для малых строк. Таким образом малые строки могут храниться в стеке, что может повысить быстродействие. Если длина строки больше некоторого порогового значения, то для хранения символов используется динамическая память.
Для обсуждаемых здесь реализаций факт, стандарт же не гарантирует непрерывность. |
|||
|
||||
| Mayk |
|
|||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Если размер строки <константы то его не статичность идёт побоку. Ссылка на Short String Optimisation уже была. Это сообщение отредактировал(а) Mayk - 1.8.2008, 05:36 -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
|||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 6 Всего: 33 |
Глупость -------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
ты учти что менеджер памяти выделяет память под маленькие объекты блоками фиксированного размера, кратными степеням двойки, под строку размером 12 байт может быть выделено 16 байт, а может и 32... плюс обращение к строке в куче дороже чем обращение к строке в стеке, плюс создание и освобождение строки в куче не дешевая операция, в отличии от создания объекта в стеке... блин, так и не понял, нафига тебе хранить кучу строк в памяти? |
|||
|
||||
| Vyacheslav |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 9 Всего: 59 |
Стандарт это не регламентирует в отличие от непрерывной памяти для vector. И c_str и data как раз могут не отражать как на самом деле хранится строка. -------------------- С уважением, Вячеслав Ермолаев |
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
||||
|
||||
| vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
стандарт может и не регламентирует, но врядли вы найдете реализацию string где итераторы не являются обычными указателями. |
|||
|
||||
| phprus |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 22.8.2006 Репутация: 1 Всего: 3 |
Задача не очень понятна. Исходные данные: 1) много файлов содержащих слова 2) новый файл со словами Возникают вопросы: Что нужно получить в результате? В случае если нужно получить один результирующий файл в котором будут все уникальные слова, то имеем элементарную задачу. Сливаем все слова в один файл, сортируем его сортировкой слиянием ( О(n*log(n)) ) и за О(н) удаляем дублирующиеся слова. Это наиболее быстрое из всех возможных решений, кроме того оно не требовательно к оперативной памяти. В некоторых случаях для решения этой задачи достаточно стандартной *nix'овой утилиты sort аналоги которой есть и под винду. Если нужно новый файл очистить от тех слов, которые есть в старых файлах, то можно слить все старые файлы в один, отсортировать его, после чего задачу поиска дублей можно решить за один проход по обоим файлам. Если что-то еще, то уточни задачу, но очень похоже, что ты что-то не то делаешь. Не похоже что-бы подобная задача требовала загрузки всех данных в память. Хэш-таблицы тут не подойдут, так как потребуется дополнительное время на из создание, а во вторых в связи с возможностью коллизий при каждом поиске нужно будет сравнивать не только вычислять и сравнивать хэш-коды, но и сравнивать сами строки, что приведет фактически к 2-х кратному росту числа проходов по данным. |
||||
|
|||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
Ну это в теории конечно так красиво. Попробуй отсортировать файл с 10 млн. слов, это займёт никак не меньше времени, чем просчёт и построение хеш-таблиц. Приведи такую коллизию для двух реально существующих слов в нашем или английском языке хотя бы для функции adler32. Это сообщение отредактировал(а) W4FhLF - 2.8.2008, 18:59 -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| Mayk |
|
||||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
а вообще можно и не руками писать. а юзать готовое
говорят, что современные базы данных умееют импортировать тектсовые файлы. Это сообщение отредактировал(а) Mayk - 2.8.2008, 19:15 -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
||||
|
|||||
| phprus |
|
||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 22.8.2006 Репутация: 1 Всего: 3 |
Проверял. Файл из 10 млн. строк длинной от 5 до 25 символов ( 152 Мб ) сотритуется на моем ноутбуке утилитой sort за 2 минуты 13 секунд. Хэш-таблица может быть более ресурсоемкой, так как требует дополнительных сравнений строк, что-бы разрешать возможные коллизии. Кроме того если сами сравниваемые строки хранить на диске, то в результате будет много чтений из различных участков файла, а это гораздо медленнее непрерывного чтения в случае сортированных файлов.
В английском языке потенциально бесконечное количество слов. 2^32 меньше бесконечности, по этому коллизии будут. Кстати я совсем забыл о существовании утилиты comm, которая умеет вот что:
Следовательно задача автора темы в случае файлов может решиться вообще без программирования. |
||||||
|
|||||||
| W4FhLF |
|
||||||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
Ну так сложно оценить. Может этот файл уже был близок к отсортированному состоянию? Однако просчёт 10 миллинов хешей на процессоре 3гц займёт ~1 сек.
Да коллизии здесь не аргумент. Число существующих слов не бесконечно. Вероятность сущестсования коллизии не нулевая, но она слишком мала. В крайнем случае можно взять 64 битную хеш-функцию. Тогда на 32х битных системах сравнение будет выполняться за 2 такта в худшем случае, а на 64 битных за 1. Допустим для подчёта контрольной суммы файлов любых размеров в интернете используется md5. Почему-то ещё никто не наткнулся на коллизию, но её вероятность тоже не нулевая. Это сообщение отредактировал(а) W4FhLF - 3.8.2008, 10:33 -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
||||||
|
|||||||
| phprus |
|
||||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 22.8.2006 Репутация: 1 Всего: 3 |
Маловероятно. Но что-бы нормально оценить нужно взять данные автора и сравнить время работы.
Процессора... А сколько памяти займет такая табличка? Она во первых потребует загрузить все слова в память, а ва вторых еще место под саму хэш-таблицу. Кроме того хэш-таблицу в памяти нужно будет каждый раз перестраивать, а вот один раз отсортированные файлы повторной сортировки не требуют.
Возьмем 64 битную хэшфункцию. Она даст нам 2^64 степени комбинаций. Предположим, что у нас такая мегафункция, что она все слова отобразила в разные значения. НО тут возникает проблема, что мы физически не можем создать хэш-таблицу с 2^64 ячеек. По этому придется этот хэш усекать и вот тут уже вероятность появления коллизий значительно возрастает, по этому приходится применять меры по разрешению коллизий и как следствие либо все данные в память, либо большое количество дорогих дисковых операций.
Для md5 можно подобрать второй файл с таким-же хэш-кодом. Кроме того задача контрольных сумм не требует 100% отсутствия коллизий. |
||||||||
|
|||||||||
| SABROG |
|
|||
![]() Hacker ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2481 Регистрация: 18.9.2006 Репутация: 4 Всего: 91 |
Для контрольной суммы пойдет и простой CRC32. Контрольная сумма и хэш разные вещи. Я не думаю что в DirectConnect просто так юзают TTH, а не Adler32.
|
|||
|
||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
Смотря что в ней хранить помимо самого хеша, если упор на скорость то ещё позицию слова и длину хранить надо. Ну для 10 млн. слов метров 100 отожрёт. Слова в памяти хранить как раз нет никакой необходимости. Можно читать файл порциями по 10-20 мегабайт и строить таблицу. А для сортировки что меньше памяти надо? Там-то как раз весь файл в памяти иметь нужно.
Зачем нам такая таблица? Кол-во записей == кол-ву слов. Можно? Ну попробуй подобрать или хотя бы в сети найти примеры таких файлов Нет, я понимаю теория великая вещь. В ней столько всего возможно, но вот практика штука более ограниченная и в ней приходится делать некоторые допущения и это будет всё прекрасно работать и решать поставленную задачу. В данной теме интерес именно прикладной, т.е. теория меня здесь не особо интересует. Добавлено через 12 минут и 54 секунды Ты прав. Я собственно adler32 предложил просто как пример очень быстрой функции и с учётом экономии памяти. Это даже не хеш-функция как таковая Вот было бы интересно взять какой-нибудь более или менее полный словарь русского/английского и посмотреть будут ли там коллизии. Вопрос где взять такой словарь? Это сообщение отредактировал(а) W4FhLF - 3.8.2008, 10:33 -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| phprus |
|
||||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 22.8.2006 Репутация: 1 Всего: 3 |
Это потребуется для разрешения коллизий. Либо все слова держать в памяти, либо в хэш-таблице придется хранить смещения в файлах данных, но это приведет к огромным дисковым тормозам.
А про алгоритмы внешней сортировки вы не слышали? Расход оперативной памяти можно сделать очень маленьким. Поиск по переполненной хэш-таблице вещь чрезвычайно медленная. Количество ячеек в таблице должно быть как минимум на треть больше чем количество записей в ней и и то при таком количестве пустых ячеек коллизии будут. Кстати а можно поинтересоваться вы вообще хоть какие-либо алгоритмы сортировки знаете? А хэш-таблицы реализовывали? Судя по тому, что вы не знаете основ говорит о том, что все-же нет.
Я то как раз и говорю про практику, а вот вы рисуете какую-то идеальную картину при том на столько идеальную, что ее даже в теории быть не может, а не то что на практике.
Алгоритм хэширования коллизий может и не дать, НО в хэш-таблице коллизии будут. Если конечно размер таблицы будет адекватный, а не такой, что количество ячеек будет равно количеству возможных значений хэш-кодов. |
||||||||
|
|||||||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
phprus, в общем видимо я где-то протормозил, но под хеш-таблицей я не имел ввиду структуру данных "hash table". Всё что я говорил про время и память касалось только лишь расчёта хешей для слов, а не их отображения в какую-либо структуру. И когда ты говорил коллизия я это понимал как hash(s1) == hash(s2). Теперь всё ясно.
Да какие дисковые тормоза? В качестве value харнить позиции слов в файле. Файл читать целиком придётся в любом случае(кусками или ещё как-нибудь). А про запись автор ничего не говорил. Он сказал, что надо проанализировать на предмет наличия дубликатов. А это не дисковые тормоза? -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| phprus |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 22.8.2006 Репутация: 1 Всего: 3 |
Вот здесь и всплывут тормоза. Даже для фрагментированного файла последовательное чтение будет быстрее, чем чтение маленьких кусочков из разных участков файла. (Тут так-же не надо забывать про то, что ОС кеширует данные с диска в оперативке, и этот кэш будет эффективнее при последовательном чтении, чем при постоянных перескоках в разные концы файла). В случае сортировки количество чтений из произвольных участков файла будет минимальным, а в случае работы с отсортированными последовательностями будет вообще только последовательное чтение. |
|||
|
||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
phprus, я понимаю в чём минусы произвольного чтения с диска. Я не понимаю зачем нам читать из разных концов файла? Мы читаем последовательно, хешируем слова, имеем их позиции и составляем из них уже любую структуру.
-------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| phprus |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 22.8.2006 Репутация: 1 Всего: 3 |
Вспомни как происходит поиск в хэш-таблице. Вначале по хэшу ищется нужная запись, а потом для того что-бы гарантировать, что это не коллизия сравниваются сами значения. То значение, которое мы ищем у нас в памяти, а вот то значение которое в хэш-таблице у нас на диске и что-бы его получить нужно считать данные с диска. При поиске следующего слова оно у нас будет в памяти, а вот ссылка из хэш-таблицы снова будет вести на диск и при том в совершенно случайную область файла исходных данных. |
|||
|
||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
phprus, всё понял, я действительно гоню
Добавлено через 6 минут и 44 секунды А что если в качестве значения использовать pair<hash, position>? Hash в любом случае вычисляется один раз, позиция известна при первом проходе. Тогда для разрешения коллизий не придётся читать с диска. Это сообщение отредактировал(а) W4FhLF - 3.8.2008, 16:44 -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| phprus |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 22.8.2006 Репутация: 1 Всего: 3 |
Не получится. На входе функции поиска у нас строка, а в хэш-таблице смещение в файле. И эти 2 сущности надо как-то сравнивать. Как следствие надо читать строку из файла. |
|||
|
||||
| Mayk |
|
|||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Вопрос,задаваемый (n+1)-ый раз:
А кто нибудь может доступным языком объяснить почему БД нельзя использовать? Это сообщение отредактировал(а) Mayk - 4.8.2008, 07:35 -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
||||
|
||||
| andrew_121 |
|
|||
![]() Кодофей ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3448 Регистрация: 3.1.2008 Репутация: 6 Всего: 33 |
Уже не надо в памяти хранить. Это так для развития, понимания... -------------------- Удалил аккаунт. Прощайте! |
|||
|
||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
В общем выдался свободный часок и я таки реализовал то, что предлагал. Т.е. считать хеши и позиции слов. Потом сортировка этого вектора и вывод дубликатов.
Перестраховался и в качестве хеша вычисляется md5 и берутся его 1 и 4 блоки. Хеш хранится в __int64. Для вычисления хеша подключил свою когда-то написанную на ассемблере оптимизированную либу для вычисления md5. Поэтому процедура string_hash слегка уродлива В конце программы в консоль выводятся слова, которые имеют дубликаты в словаре. Словари для тестов брал отсюда: http://www.insidepro.com/eng/download.shtml На моём процессоре AMD 2.2 гц на построение таблицы и её сортировку для словаря 2.5 млн. слов уходит ~5 секунд. Меня такой результат вполне удовлетворил так, что решил оставить реализацию как есть. Проект для VS 2008 в аттаче.
Присоединённый файл ( Кол-во скачиваний: 2 )
words_unify.rar 5,21 Kb-------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |