Строковое управление памятью C++

В gdb вы можете многое сделать, чтобы изменить поведение вашей программы, когда она достигает точки останова без остановок. Команда печати также может быть использована для изменения значений, например, print i=0 фактически устанавливает i в ноль.

Просто помните, что все эти изменения и взломы должны быть перенесены обратно в исходный код и протестированы снова! За прошедшие годы я потерял много отличных правок, выполняя встроенные хаки в коде, а затем завершал работу, не просматривая изменения.

12
задан Dan Byström 4 March 2009 в 13:24
поделиться

9 ответов

Вы ступаете в обувь Raymond Chen. Он сделал ту же самую вещь, пишущий китайский словарь в неуправляемом C++. Rico Mariani сделал также, пишущий это в C#. Г-н Mariani сделал одну версию. Г-н Chen записал 6 версий, пытаясь соответствовать перфекту версии Mariani. Он в значительной степени переписал значительные блоки библиотеки времени выполнения C/C++ для получения там.

Управляемый код получил намного больше уважения после этого. Средство выделения GC невозможно разбить. Проверьте это сообщение в блоге на ссылки. Это сообщение в блоге могло бы заинтересовать Вас также, поучительный, чтобы видеть, как семантика значения STL является частью проблемы.

11
ответ дан 2 December 2019 в 03:12
поделиться

Это очень кажется, что Raymond Chen по сравнению с C++ Rico Mariani по сравнению с китайским/Английским исполнением словаря C# печет прочь. Raymond потребовались несколько повторений для избиения C#.

Возможно, существуют идеи там, которые помогли бы.

http://blogs.msdn.com/ricom/archive/2005/05/10/performance-quiz-6-chinese-english-dictionary-reader.aspx

12
ответ дан 2 December 2019 в 03:12
поделиться

Черт. избавьтесь от CStrings...

судите профилировщика также. действительно ли Вы уверены, что только выполняли код отладки?

станд. использования:: строка вместо этого.

Править:

Я просто сделал простой тест ctor и dtor сравнений.

CStringW, кажется, берет между 2 и 3 раза временем, чтобы сделать новое/удал.

выполненный с помощью итераций, 1000000 раз делая новый/удаляющий для каждого типа. Ничто иное - и GetTickCount () вызов прежде и после каждого цикла. Последовательно добирайтесь дважды, как жаждут CStringW.

Это не решает Вашу всю проблему, хотя я подозреваю.

Править: Я также не думаю, что использование строки или CStringW является реальным проблема - существует что-то еще продолжающееся, который вызывает Вашу проблему.

(но ради бога, используйте stl так или иначе!)

Необходимо представить его. Это - авария.

10
ответ дан 2 December 2019 в 03:12
поделиться

Если это - словарь только для чтения затем, следующее должно работать на Вас.

Use fseek/ftell functionality, to find the size of the text file.

Allocate a chunk of memory of that size + 1 to hold it.

fread the entire text file, into your memory chunk.

Iterate though the chunk.

    push_back into a vector<const char *> the starting address of each line.

    search for the line terminator using strchr.

    when you find it, deposit a NUL, which turns it into a string.
    the next character is the start of the next line

until you do not find a line terminator.

Insert a final NUL character.

Можно теперь использовать вектор, для получения указателя, который позволит Вам получить доступ к соответствующему значению.

Когда Вы закончите со своим словарем, освободите память, позвольте вектору умереть при выходе из объема.

[РЕДАКТИРОВАНИЕ] Это может быть немного более сложно на платформе DOS как разделитель строки, является CRLF.

В этом случае используйте strstr, чтобы найти, что он, и инкремент 2 находит запуск следующей строки.

4
ответ дан 2 December 2019 в 03:12
поделиться

В каком контейнере Вы храните свои строки? Если это - a std::vector из CStringW и если Вы не имеете reserve- редактор достаточно памяти заранее, Вы обязаны получить удар. A vector обычно изменяет размер, после того как это достигает, это - предел (который не очень высок), и затем копирует полноту к новой ячейке памяти, которая является, может дать Вам большой хит. Как Ваш vector растет экспоненциально (т.е. если начальный размер равняется 1, в следующий раз, когда он выделяет 2, в 4 следующих раза вперед, хит становится все меньше и меньше частым).

Это также помогает знать, какой длины отдельные строки. (Время от времени :)

3
ответ дан 2 December 2019 в 03:12
поделиться

Загрузите строку в единственный буфер, проанализируйте текст для замены разрывов строки строковыми разделителями ('\0'), и указатели использования в тот буфер для добавления к набору.

Кроме того - например, если необходимо сделать, преобразование ANSI/UNICODE во время загрузки - использует средство выделения блока, которое жертвует отдельными элементами удаления.

class ChunkAlloc
{
   std::vector<BYTE> m_data;
   size_t m_fill;
   public:
     ChunkAlloc(size_t chunkSize) : m_data(size), m_fill(0) {}
     void * Alloc(size_t size)
     {
       if (m_data.size() - m_fill < size)
       {
          // normally, you'd reserve a new chunk here
          return 0;
       }
       void * result = &(m_data[m_fill]);
       m_fill += size;
       return m_fill;
     }
}
// all allocations from chuunk are freed when chung is destroyed.

Не взломал бы это вместе через десять минут, но 30 минут, и некоторое тестирование звучит прекрасным :)

2
ответ дан 2 December 2019 в 03:12
поделиться

Спасибо все Вы для Ваших проницательных комментариев. Upvotes для Вас!:-)

Я должен признать, что не был подготовлен к этому вообще - что C# разобьет живущее дерьмо из старого доброго C++ таким образом. Не читайте, что как преступление к C++, но вместо этого что удивительно хороший диспетчер памяти, который находится в Платформе.NET.

Я решил предпринять шаги назад и вести этот бой на арене InterOp вместо этого! Таким образом, я сохраню свой код C# и позволю моему старому C++ кодировать, говорят с кодом C# по COM-интерфейсу.

Много вопросов спросили о моем коде, и я попытаюсь ответить на некоторых из них:

  • Компилятором была Visual Studio 2008 и не, я не выполнял отладочную сборку.

  • Файл был считан со средством чтения файлов UTF8, которое я загрузил от сотрудника Microsoft, который опубликовал его на их сайте. Это возвратило CStringW, и приблизительно 30% времени были на самом деле потрачены, там просто читая файл.

  • Контейнер, в котором я сохранил строки, был просто вектором фиксированного размера указателей на CStringW, и он никогда не изменялся.

Править: Я убежден, что предложения, которые мне дали, будут действительно работать, и что я, вероятно, мог победить код C#, если бы я инвестировал достаточно времени в него. С другой стороны, выполнение так не обеспечило бы клиентского значения вообще, и единственная причина выжить с ним будет состоять в том, чтобы только доказать, что оно могло быть сделано...

3
ответ дан 2 December 2019 в 03:12
поделиться

При работе со строковыми классами необходимо всегда взглянуть на ненужные операции, например, не используйте конструкторов, конкатенацию и такие операции слишком часто, особенно избегайте их в циклах. Я предполагаю, что существует некоторая причина кодировки символов, что Вы используете CStringW, таким образом, Вы, вероятно, не можете использовать что-то другое, это было бы другим способом оптимизировать Ваш код.

1
ответ дан 2 December 2019 в 03:12
поделиться

Проблема не в CString, а в том, что вы выделяете много маленьких объектов - распределитель памяти по умолчанию не оптимизирован для этого.

Напишите свой собственный распределитель - выделите большой кусок памяти, а затем просто переместите указатель в него при распределении. Это то, что на самом деле делает распределитель .NET. Когда будете готовы, удалите весь буфер.

Я думаю, что был образец написания пользовательских операторов new / delete в (More) Effective C ++

3
ответ дан 2 December 2019 в 03:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: