Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Что влияет на скорость функции

490
27 сентября 2007 года
frid-karatel
357 / / 15.09.2007
Есть функция, которая загружает файл (около 16 Мб) в память, считывает побайтно каждый байт и производит с ними разные операции: сравнивает, добавляет, копирует, удаляет и т.п.

Так вот... Что влияет на скорость выполнения функции? Как ее увеличить? Например, что лучше делать: назначать значение переменной и потом сравнивать переменную, или сразу сравнивать значение? Как поступить - использовать визуальные компоненты или грузить все в файл? Где лучше хранить данные - в AnsiString или char? Да и вообще, как лучше перебрать каждый байт в файле, если их необходимо сравнивать с заранее определенной байтовой строкой?

PS: думаю меня не накажут за такой вопрос, а просто дадут ссылки на справку, иначе просто я не знаю, как корректно задать вопрос в поисковик...
Страницы:
276
27 сентября 2007 года
Rebbit
1.1K / / 01.08.2005
Не уверен, но скорее всего самое медленное место ето читание байта. Попробуй читать сразу 1024 (2048) байта в буфер, а потом брать байти оттуда.
30K
27 сентября 2007 года
pilgrim.sa
9 / / 12.09.2007
Цитата: frid-karatel
Есть функция, которая загружает файл (около 16 Мб) в память, считывает побайтно каждый байт и производит с ними разные операции: сравнивает, добавляет, копирует, удаляет и т.п.

Так вот... Что влияет на скорость выполнения функции? Как ее увеличить? Например, что лучше делать: назначать значение переменной и потом сравнивать переменную, или сразу сравнивать значение? Как поступить - использовать визуальные компоненты или грузить все в файл? Где лучше хранить данные - в AnsiString или char? Да и вообще, как лучше перебрать каждый байт в файле, если их необходимо сравнивать с заранее определенной байтовой строкой?

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


Я не спец по Builder'u, так как пользуюсь VC, но от себя могу сказать следующее (с точки зрения стандартного C/C++):

>что лучше делать: назначать значение переменной и потом сравнивать переменную, или сразу сравнивать значение?

Если однобайтовая переменная, то лучше сразу сравнивать значение и писать в нее если нужно. Если многобайтовая (например long), то лучше использовать адрес переменной или ссылку (принципиальной разницы нет)

>Да и вообще, как лучше перебрать каждый байт в файле, если их необходимо сравнивать с заранее определенной байтовой строкой

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

30K
27 сентября 2007 года
pilgrim.sa
9 / / 12.09.2007
Update:
В гугле нашел...
memcmp() - compare two memory regions

Это будет самое бастрое для сравнения строк, если они представлены цепочкой байт в памяти
490
27 сентября 2007 года
frid-karatel
357 / / 15.09.2007
У меня в программе как: получается, что цикл от 0 до 16 000 000 (около того) . В цикле есть около 100 строк кода сравнения... присваивания... и т.п. вещей... плюс статус-бар с отображением... чего не следует использовать в этом цикле, каких функций и операций, каких типов переменных и т.п. вещей?
10K
27 сентября 2007 года
FAngel
77 / / 13.09.2006
Цитата: frid-karatel
У меня в программе как: получается, что цикл от 0 до 16 000 000 (около того) . В цикле есть около 100 строк кода сравнения... присваивания... и т.п. вещей... плюс статус-бар с отображением... чего не следует использовать в этом цикле, каких функций и операций, каких типов переменных и т.п. вещей?


Всего что можно сделать один раз за пределами цыкла. И вообще, я незнаю какая конкретно задача решается этим циклом, но мне кажется что тебе надо основательно менять алгоритм ее решения(что-то больно:eek: много у тебя итераций). Кроме того в большинстве книг написано как лучше организовывать циклы, чтобы они работали быстрее.

12K
28 сентября 2007 года
__AleXX__
133 / / 02.04.2007
Цитата: frid-karatel
У меня в программе как: получается, что цикл от 0 до 16 000 000 (около того) . В цикле есть около 100 строк кода сравнения... присваивания... и т.п. вещей... плюс статус-бар с отображением... чего не следует использовать в этом цикле, каких функций и операций, каких типов переменных и т.п. вещей?



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

Более-менее общие соображения были высказаны.

От себя могу добавить, что:
1. желательно в цикле меньше дублировать информацию (т.е. лишний раз копировать),
2. функции для работы с памятью обычно называются mem...
3. считывать, если можно, действительно, быстрее будет не по байту, а большими порциями, как было предложено (если есть, конечно, возможность)

Пока всё, если что-нить придумается - напишу

252
28 сентября 2007 года
koderAlex
1.4K / / 07.09.2005
asm знаеш ?
3.2K
28 сентября 2007 года
nikipelovav
152 / / 12.04.2006
Ещё один совет. Оптимизируй работу с прогресс шкалой.

Builder предлагает два варианта шкалы TProgressBar и TCGauge.

Когда-то Я столкнулся с проблемой ОГРОМНОГО торможения при использовании TCGauge! Вызывая некоторый метод ShowProgress ( int Max, int Mid, int Min ) , в этом методе всегда присваивались значения не только текущей позиции - Mid, но и максимальной - Max, и минимальной - Min. Так вот, даже, при условии, что Max и Min всегда были одинаковы, складывалось ощущение, что компонента TCGauge при присвоении значений этим свойствам выполняла какие-то методы "подготовительной инициализации" и это очень тормозило перерисовку шкалы! Пришлось проверять текущее значение границ шкалы с новыми - Min и Max, и присваивать новые значения только в случае отличия. Скорость работы резко увеличилась!

Также, можно отсекать "выстрелы в холостую". У тебя 16 000 000 итераций. Шкала отображает 100, это значит что на 160 000 итераций приходится одно уникальное состояние шкалы. Зачем это состояние заставлять перерисовавать 160 000 раз? Если подобной оптимизации нет у TProgressBar (а у TCGauge и подавно), реализуй её сам.

Вот пример:

Код:
// в этом примере
// int FMax - максимальное значение
// int FMid  - текущее значение прогресса
// int FMin  - минимальное значение
// const int ProgressMAX = 100
// ProgressBar - указатель на TCGauge

int SetProgress ( int Value )
{
   int x0,x1;
   x0 = ((FMid - FMin)*ProgressMAX)/(FMax - FMin);
   x1 = ((Value - FMin)*ProgressMAX)/(FMax - FMin);

   FMid = Value;

   // если новое значение не изменит процент выполнения
   // незачем перерисовывать шкалу прогресса
   if ( x0 == x1 ) return;

   // перерисуем шкалу
   ProgressBar->Progress = Value;

   // обработаем сообщения приложения, в том числе и "перерисовку шкалы"
   Application->ProcessMessages();
}

int SetProgressMax ( int Value )
{
   // сохраним значение во внешней переменной
   FMax = Value;

   // "перерисуем" если в этом есть необходимость
   if ( ProgressBar->MaxValue != Value ) ProgressBar->MaxValue = Value;

   // обработаем сообщения приложения, в том числе и "перерисовку шкалы"
   Application->ProcessMessages();
}
490
28 сентября 2007 года
frid-karatel
357 / / 15.09.2007
Цитата: nikipelovav
Ещё один совет. Оптимизируй работу с прогресс шкалой.



Я использую нестандартный компонент от JEDI Lib...

У меня значение максимума в нем равно 32, т.к. показываются только 32 деления...

С объектом я работаю тогда, когда есть необходимость увеличить его значение на 1. А это требуется в таком случае:

Допустим,
MyMemoryStream->Size = 16 000 000
MyProgressBar->Max = 32
for (unsigned long uc = 0; uc < MyMemoryStream->Size; uc++)
{
if (MyProgressBar->Max * uc / MyMemoryStream->Size > MyProgressBar->Position)
{
MyProgressBar->Position++;
}
}
Конечно, вместо обектов и параметров объектов я использую переменные, имхо обращаться к обектам каждый раз для сравнения - это затраты по времени...

В-общем, суть в том, что я сначала проверяю - а стоит ли увеличивать значение ProgressBar или не стоит...

490
28 сентября 2007 года
frid-karatel
357 / / 15.09.2007
Приведу примерный код функции, которую необходимо ускорить:

Код:
AnsiString ts = "4F006B0000004200610063006B00";
  const ucLength = 1000;
  int tsLength = ts.Length();
  unsigned char uc[ucLength];
  TMemoryStream *ms = new TMemoryStream();
  ms->LoadFromFile(ExtractFilePath(Application->ExeName) + "temp.bin");
  unsigned long a = 0;
  AnsiString s;
  int b;
  /***/
  TDateTime dt1, dt2;
  dt1 = Now();
  /***/
  while (a < ms->Size)
  {
    ms->Seek(a, soFromBeginning);
    ms->Read(&uc, ucLength);
    s = "";
    for (b = 0; b < ucLength; b++)
    {
      s = s + IntToHex(uc, 2);
    }
    if (s.Pos(ts) > 0)
    {
      break;
    }
    a = a + ucLength - tsLength / 2;
  }
  /***/
  dt2 = Now();
  AnsiString buff;
  DateTimeToString(buff, "ss:zzz", dt2 - dt1);
  Button2->Caption = buff;


Здесь я выполняю функцию и проверяю ее скорость...
Размер файла около 16 Мб, хотя может быть и больше...
Мне необходимо найти HEX-значение в этом всем файле, а потом уже от адреса найденного и плясать... что плясать - это уже не важно, главное - как быстро найти?

PS: на моем Intel Pentium D 3.4 GHz x 2 уходит около 10 секунд - мне бы хотелось управиться за 5... как максимум, а вообще - секунды за 2-3...
3.2K
28 сентября 2007 года
nikipelovav
152 / / 12.04.2006
У TMemoryStream есть свойство Memory - void указатель на блок памяти данных потока. Код не проверял, если есть ошибки - просьба не выражаться ;)

Код:
AnsiString ts = "4F006B0000004200610063006B00";

// преобразуем СТРОКУ  в  БИНАРНЫЙ МАССИВ

int i,j = StrLen( ts.c_str() )/2;
char* sbin = new char[j]; char* psbin = sbin;
AnsiString str;
for ( i = 0; i < j; i++ )
{
  // берём 2 символа
  str = ts.SubString(1+i*2,2);

  // преобразуем в char и добваляем sbin
  HexToBin( str.c_str(), psbin, 1 );

  // к следующему
  psbin++;
}

// в результате массив sbin содержит твою строку в двоичном виде

// далее читаем файл, и объявляем указатель на массив прочитанных данных в памяти,
// благо TMemoryStream позволяет это сделать

TMemoryStream *ms = new TMemoryStream();
ms->LoadFromFile(ExtractFilePath(Application->ExeName) + "temp.bin");
ms->Position = 0; // в начало данных
char* pMem = (unsigned char*)ms->Memory;
char* pMemTemp  = pMem; // временный указатель
char* pMemFound = pMem; // указатель на адрес совпадения

unsigned long a = 0; bool found = true;

while ( a < (ms->Size - j) )
{
  found     = true;     // предполагаем, что нашли
  pMemFound = pMemTemp; // запомним место
  psbin     = sbin;     // в начало массива, который ищем

  for ( i = 0; i < j )
  {
    if ( *pMemTemp != *psbin )  // если несовпадение - прерываемся
      {
        found = false;
        if ( i == 0 )    // к следующему, только если он первый (чтобы не зависнуть!)
          {
            a++;         // условие выхода из цикла
            pMemTemp++;  // к следующему байту массива данных
          }
        break;           // прерываемся
      }
    else
      {
        a++;             // условие выхода из цикла
        pMemTemp++;      // к следующему байту массива данных
      }

    psbin++;             // к следующему байту искомого массива
  }

  if ( found ) break;           // если нашли - выходим
}

if ( found ) // если нашли - делай что хочеш
  {
    ;)))  - pMemFound
  }
490
28 сентября 2007 года
frid-karatel
357 / / 15.09.2007
Цитата: nikipelovav
У TMemoryStream есть свойство Memory - void указатель на блок памяти данных потока. Код не проверял, если есть ошибки - просьба не выражаться ;)



Ок... попробую.... не выражаться :)

Получается, что здесь от обратного - не в HEX найденное, а искомое в unsigned char... т.е. в BIN...

Но все равно функция перебирает каждый байт файла... так? Это же кошмар, млин :)...

я вот тут часиков эдак 10-14 пытался блоками научить читать... так ничего и не вышло... мучался-мучался, так и не понял, как сравнить два unsigned char'a, т.е. найти вхождение одного в другой... если unsigned char заданы как uc1[50] и uc2[200]... Циклом только что-ли?

PS: а функцию попробую применить - может чего и выжму из нее... ;)

3.2K
29 сентября 2007 года
nikipelovav
152 / / 12.04.2006
Думаю быстрее перебирать байтики, чем ... делать тоже самое! , но со строками
 
Код:
... s = s + IntToHex(uc, 2);
... if (s.Pos(ts) > 0)

Согласись, это намного дольше!

Тот пример, что Я написал работает только со строками, в которых нет повторяющихся фрагментов. Если есть - поиск может пропустить нужную строку. Но, зато поиск идёт быстрее.

Объясню:

Например ты ищешь строку "asDasF" в массиве "asDasDasFaaaaaaa"
В моём алгоритме "несовпадение" в 6-м символе F / D.

asDas[F]
asDas[D]asFaaaaaaa

И следующий шаг сравнения начнётся именно с символа D.

_____[a]sDasF
asDas[D]asFaaaaaaa

А ведь искомая строка ЕСТЬ: asD[asDasF]aaaaaaa


Универсальный метод: пошаговое (смещение на 1 байт в цикле while) сравнение массивов с помощью memcmp().
490
30 сентября 2007 года
frid-karatel
357 / / 15.09.2007
Спасибо, nikipelovav! Код действительно работает быстрее раза в 3, чем я использовал до... ;)
490
30 сентября 2007 года
frid-karatel
357 / / 15.09.2007
Есть еще один код, которые не внушает у меня доверия к скорости... :) Он чуть побольше...

Код:
AnsiString slCell[5];  //Для хранения полученных ячеек, т.к. не придумаю, как правильней в результате функции выдать массив...
TStringList *slGrid; //Хранит данные в виде таблицы в памяти для быстрой обработки
//Формат задан так: имеется 5 псевдоячеек, разделенных табуляцией, т.е.
//String1\tString2\tString3\tString4\tString5

/*
Итак, что происходит...
Загружается файл в псевдотаблицу, т.е. в память, т.к. если использовать визуальную таблицу - скорость резко сокращается... :(
В таблице есть пять столбцов... нам важны пока первые два - остальные - служебные...
В первом столбце находится оригинальное значение, во втором будет находиться замененное...

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

Для поиска и замены служит функция FindAndReplace()...
Что требуется - если строк больше 2000, то обработка способом, который я использую слишком долгая... желательно бы ускорить процесс...
Есть идея - использовать sl->IndexOf(AnsiString Value), но проблема в том - она ищет точное совпадение строки, а не часть...

Конечно, может есть и другие варианты, например, использовать не TStringList, а TMemoryStream, но вотв нем вообще нет стандартного поиска...
*/

//---------------------------------------------------------------------------
void __fastcall TForm1::slGetCells(int gRow)  //Получение всех ячеек в определенной строке
{
  AnsiString buff = slGrid->Strings[gRow];
  for (int a = 0; a < 5; a++)
  {
    slCell[a] = buff.SubString(1, buff.Pos('\t') - 1);
    buff.Delete(1, buff.Pos('\t'));
  }
}
//---------------------------------------------------------------------------
AnsiString __fastcall TForm1::slReadCell(int gCol, int gRow)  //Чтение из псевдотаблицы
{
  slGetCells(gRow);
  return slCell[gCol];
}
//---------------------------------------------------------------------------
void __fastcall TForm1::slWriteCell(int gCol, int gRow, AnsiString gValue)  //Запись в псевдотаблицу
{
  AnsiString buff = "";
  slGetCells(gRow);  //Получаем всю строку, т.е. все 6 ячеек
  slCell[gCol] = gValue;  
  for (int a = 0; a < 5; a++)
    buff = buff + slCell[a] + "\t";
  slGrid->Strings[gRow] = buff;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FindAndReplace()
{
  AnsiString buff;
  int slPos;

  TStringList* sl = new TStringList();
  sl->LoadFromFile(ExtractFilePath(Application->ExeName) + "zameni.txt");  //Загружаем строки из файла
  //Формат строк: "Оригинальное значение\tЗначение для замены"

  for (int a = 0; a < sl->Count; a++) //Перебираем все строки
  {
    slPos = sl->Text.Pos(slReadCell(0, a) + "\t");  //Ищем требуемое значение
    if (slPos > 0) //Если нашли значение, то...
    {
      buff = sl->Text.SubString(slPos, slReadCell(0, a).Length() * 2 + 20);  //Читаем в буфер с запасом в 20 символов
      buff = buff.SubString(buff.Pos('\t') + 1, buff.Pos('\n') - buff.Pos('\t') - 2);  //Выделяем из строки второю псевдоячейку, т.е. которая содержит замену
      slWriteCell(1, a, buff);  //Записываем значение в псевдотаблицу во второй столбик, т.к. первый содержит оригинал

      toDel = sl->IndexOf(slReadCell(0, a) + "\t" + slReadCell(1, a));  //ищем в списке необходимую строку, т.е. совпадающую как 1 и 2 ячейки...
      if (toDel != -1)  //Если строка найдена...
        sl->Delete(toDel);  //Удаляем, чтобы не мешалась - она больше не нужна
    }
  }
  sl->Free();  //Освобождаем память
}
245
30 сентября 2007 года
~ArchimeD~
1.4K / / 24.07.2006
совсем чуток так поправлю

есть у тя умножение на 2 в цикле - если заменить на сдвиг, может немного ускориться.

где можно используй не var-1, а var-- (аналогично и с плюсом;) ) не знаю как твой компилятор обрабатывает, но может в первом случае грузить оба числа в регистры и затем вычитать, а во втором - загрузить одно, а потом просто выполнить над ним операцию dec. понятно, что для больших циклов второй случай побыстрее будет.

но это так, небольшие мазки...
3.2K
01 октября 2007 года
nikipelovav
152 / / 12.04.2006
Рассмотрим цикл
 
Код:
for (int a = 0; a < sl->Count; a++) //Перебираем все строки
   ...

1) slReadCell встречается 3 раза, а ведь она даёт один и тотже результат, но на её выполнение уходит несколько вызовов функций и множество операций со строками.

Совет: сохрани результат первого вызова в строке, которую используй вместо второго и третьего вызова.

2) Зачем при поиске для удаления использовать "чтение" 2-го значения slReadCell(1, a), если ты его перед этим записал из buff?

Совет: замени вызов функции slReadCell(1, a) на buff.

Вот, что получится:
Код:
AnsiString TempStr;
  for (int a = 0; a < sl->Count; a++) //Перебираем все строки
  {
    TempStr = slReadCell(0, a);

    slPos = sl->Text.Pos( TempStr + "\t");  //Ищем требуемое значение
    if (slPos > 0) //Если нашли значение, то...
    {
      buff = sl->Text.SubString(slPos, TempStr.Length() * 2 + 20);  //Читаем в буфер с запасом в 20 символов
      buff = buff.SubString(buff.Pos('\t') + 1, buff.Pos('\n') - buff.Pos('\t') - 2);  //Выделяем из строки второю псевдоячейку, т.е. которая содержит замену
      slWriteCell(1, a, buff);  //Записываем значение в псевдотаблицу во второй столбик, т.к. первый содержит оригинал

      toDel = sl->IndexOf( TempStr + "\t" + buff );  //ищем в списке необходимую строку, т.е. совпадающую как 1 и 2 ячейки...
      if (toDel != -1)  //Если строка найдена...
        sl->Delete(toDel);  //Удаляем, чтобы не мешалась - она больше не нужна
    }
  }
3.7K
01 октября 2007 года
_lobster_
115 / / 10.04.2005
Могу дать пару советов:
1. Пользуйся средствами WinAPI, а если быть точнее, чтобы не грузить файл целиком, можно использовать CreateFileMap, время чтения сократиться значительно;
2. Читать, все-таки, файл не побайтно, а буфером, скажем так, 512Кб.
490
02 октября 2007 года
frid-karatel
357 / / 15.09.2007
Несколько вопросов...:
- А нельзя выполнить поиск в TStringList с использованием подстановочных знаков, например, звездочки, чтобы получить индекс строки с совпадением?
- Как прочитать сразу куском? Всмысле, как потом найти значение в этом куске? И как его обрабатывать?
- CreateFileMap используется для громадных файлов, скажем, 500Мб, 1Гб и т.д... не знаю, стоит ли использовать такой сложный (!) алгоритм для поиска...
- Archimed, что значит "заменить на сдвиг"?
3.7K
02 октября 2007 года
_lobster_
115 / / 10.04.2005
Цитата: frid-karatel

- Как прочитать сразу куском? Всмысле, как потом найти значение в этом куске? И как его обрабатывать?


Используюя WinAPI функцию ReadFile, в которой третьим и четвертым параметром идет количество байт для четния в буфер. Буфер является char*.

Цитата: frid-karatel

- CreateFileMap используется для громадных файлов, скажем, 500Мб, 1Гб и т.д... не знаю, стоит ли использовать такой сложный (!) алгоритм для поиска...


Необязательно для больших файлов. Фактически эту технику мелгомягкие ввели для загрузки исполняемых файлов в память, при этом ее не выделяя. Грузить можно файлы любого размера, правда есть одна загвоздка: как только был создан такой файл, его pазмеp не может изменяться до закpытия сессии. НИЧЕГО СЛОЖНОГО В ИСПОЛЬЗ

490
03 октября 2007 года
frid-karatel
357 / / 15.09.2007
Получается, если использовать буфер размером не 1, а, например, 256, то искать в нем как?

И как быть с остальными вопросами? (см. пост ранее)
3.7K
03 октября 2007 года
_lobster_
115 / / 10.04.2005
Цитата: frid-karatel

И как быть с остальными вопросами? (см. пост ранее)



Сорри, не посмотрел, что отправил. Опера чуть гонит.

1. Пример работы с CreateFileMap

Код:
HANDLE hFileRead=NULL,hMapFile=NULL;
 LPVOID pMemory=NULL;
 LARGE_INTEGER lpFileSize;
 hFileRead=CreateFile("\\\\.\\PhysicalDrive0",GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL);
 if (hFileRead!=NULL)
 {
    hMapFile=CreateFileMapping(hFileRead,NULL,PAGE_READONLY,0,0,NULL);
    if(hMapFile)
    {
        pMemory=MapViewOfFile(hMapFile,FILE_MAP_READ,0,0,0);
        //в pMemory лежит указатель на содержимое файла
        //здесь делаем все, что нужно

        Memo1->Lines->Text = (AnsiString)(char *)pMemory;
        UnmapViewOfFile(pMemory);
    }
    CloseHandle(hMapFile);
 }
 CloseHandle(hFileRead);

2. Какими красивыми и удобными нибыли VCL классы, все равно они остаются медленными
490
04 октября 2007 года
frid-karatel
357 / / 15.09.2007
а если использовать для хранения не TstringList и собственные процедуры (slReadCell(...), slWriteCell(...)), а использовать свой собственный клас, который создам? Скорость работы будет больше?
PS: с точки зрения удобства использования и вызова класс все-таки лучше... или нет?
3.7K
04 октября 2007 года
_lobster_
115 / / 10.04.2005
Цитата: frid-karatel
а если использовать для хранения не TstringList и собственные процедуры (slReadCell(...), slWriteCell(...)), а использовать свой собственный клас, который создам? Скорость работы будет больше?
PS: с точки зрения удобства использования и вызова класс все-таки лучше... или нет?



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

Код:
char *substring(const char *instr,int startpos,int length)
{
    char *outstr = new char[length];
    for (int i=0;i<length;i++)
    {
         (char)*(outstr+i) = (char)*(instr+i);
    }
    return outstr;
}
void main()
{
 HANDLE hFileRead=NULL,hMapFile=NULL;
 LPVOID pMemory=NULL;
 LARGE_INTEGER lpFileSize;
 char *target = "hello world";
 hFileRead=CreateFile("c:\file.txt",GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL);
 if (hFileRead!=NULL)
 {
    hMapFile=CreateFileMapping(hFileRead,NULL,PAGE_READONLY,0,0,NULL);
    if(hMapFile)
    {
        pMemory=MapViewOfFile(hMapFile,FILE_MAP_READ,0,0,0);
        for (int i=0;i<(strlen(pMemory)-strlen(target));i++)
        {
           if (pMemory==target[0])
          {
             if (strcmp(substring(pMemory+i,i,strlen(target)),target)==0)
              //подстрока найдена
          }

    }

       
        UnmapViewOfFile(pMemory);
    }
    CloseHandle(hMapFile);
 }
 CloseHandle(hFileRead);
}
490
04 октября 2007 года
frid-karatel
357 / / 15.09.2007
попробую - отпишусь ;)

А как быть с хранением данных? Дело в том, что мне в итоге необходимо вывести их в таблицу, но если постоянно обращаться к таблице, то будут большие затраты по скорости - в итоге я создал TStringList, в котором и хранится псевдотаблица... работа с памятью всегда быстрее, чем с визуальным объектом формы...

Что придумать для хранения? Есть ли альтернативные методы?
3.7K
04 октября 2007 года
_lobster_
115 / / 10.04.2005
Цитата: frid-karatel
попробую - отпишусь ;)

А как быть с хранением данных? Дело в том, что мне в итоге необходимо вывести их в таблицу, но если постоянно обращаться к таблице, то будут большие затраты по скорости - в итоге я создал TStringList, в котором и хранится псевдотаблица... работа с памятью всегда быстрее, чем с визуальным объектом формы...

Что придумать для хранения? Есть ли альтернативные методы?



Массив структур:
struct
{
char line1[255];//это первый столбец твоей таблицы
char line2[255];//--------второй
}TableLine;
..........
TableLine* table = new TableLine[/*любое количество элементов, на сколько хватит памяти*/];
table[1].line - будет указатель на строку, table[1].line[0] - первый симовол строки.
Сравнение строк происходит с помощью функции strcmp.
С заменой нужно думать, если длины строк искомой и заменямой разные, вручную необходимо производить циклические сдвиги симоволов, иначе затрешь или оставишь пробелы.

490
06 октября 2007 года
frid-karatel
357 / / 15.09.2007
Хорошо... а как можно быстрей вывести данные в таблицу.
Получается, я провел все необходимые операции - теперь мне надо из псевдотаблицы вывести все значения в Grid на форме...

Есть ли какие-нибудь "изощренные" формы вывода? А то дело в том, что если использовать стандартный вовод по циклу while (a < iEnd) с добавлением строк в таблицу, то выходит очень долго (для 3000 строк около 17 секунд)...

Как быть?
3.7K
06 октября 2007 года
_lobster_
115 / / 10.04.2005
Цитата: frid-karatel
Хорошо... а как можно быстрей вывести данные в таблицу.
Получается, я провел все необходимые операции - теперь мне надо из псевдотаблицы вывести все значения в Grid на форме...

Есть ли какие-нибудь "изощренные" формы вывода? А то дело в том, что если использовать стандартный вовод по циклу while (a < iEnd) с добавлением строк в таблицу, то выходит очень долго (для 3000 строк около 17 секунд)...

Как быть?


Может тебе лучше использовать ListView? причем на уровне WinAPI.....без цикла ничего не получится, даже обычным копированием памяти. А просто использование функций класса TStringGrid тоже влечет за собой работы циклов.

3.2K
06 октября 2007 года
nikipelovav
152 / / 12.04.2006
Вывод всех данных - дело долгое, и, возможно не нужное...

Ты не думал, всётаки работать с таблицей.

Вот ссылка http://www.aidaim.com/products/delphi.php#sqlmemtable на свободно распространяемый компонент "SQL таблица в памяти". Изучи её, может это неплохой вариант. И в работе с сеткой таблицы будет побыстрее. ;)

Достоинство этой библиотеки - встороенный движок базы данных.
490
08 октября 2007 года
frid-karatel
357 / / 15.09.2007
Под выводом данных в таблицу я имел ввиду прорисовку данных в таблице, т.е. у меня есть данные в памяти - если выводить их в компонент VCL на форме, то чем больше строк - тем медленнее - в итоге 3000 стрк в таблицу выводится аж за 14 секунд... что можно тут сделать?
3.2K
08 октября 2007 года
nikipelovav
152 / / 12.04.2006
Что-то здесь не так ;)

У меня в программе ( можешь скачать тестовый проект ProjBeam в разделе "Другое" ) 7200 строк, JOIN SQL запрос. В режиме BDE длительность отображения данных 0,6 - 0,9 секунды. Не вижу препятствий для использования движка БД в работе с твоими строками.

Что касается продукта AidAim, тут ситуация неоднозначная. С моими данными их драйвер БД Accuracer 4.2 - тормозит. Длительность загрузки данных до 5 секунд. Но Accuracer берёт данные с диска, а компонента, о которой я писал ранее - SQLMemTable - из памяти. Возможно скорость будет выше. В любом случае это не "14 секунд", как ты пишешь. Напомню о приятном преимуществе продукта AidAim - не нужен внешний драйвер БД, вся функциональность в exe файле твоей программы.

А тормоза VCL компонента, отображающего массив строк понятны. Как минимум это из-за того, что строковые значения каждой ячейки - самостоятельные строки AnsiString. Двумерный массив структур с указателями на эти строки обрабатывается долго. Другое дело таблица данных. Как я понимаю она представляет собой линейный массив данных в памяти. Размер строковых полей постоянен и известен, считывание строк для отображения - выбор блока фиксированного размера, затем с известным (размер поля) смещением следующий блок и т.д. Уверен - так быстрее.
268
08 октября 2007 года
Михаил
587 / / 25.06.2005
Цитата: frid-karatel
Под выводом данных в таблицу я имел ввиду прорисовку данных в таблице, т.е. у меня есть данные в памяти - если выводить их в компонент VCL на форме, то чем больше строк - тем медленнее - в итоге 3000 стрк в таблицу выводится аж за 14 секунд... что можно тут сделать?


выводи не все, а только те что видны

490
09 октября 2007 года
frid-karatel
357 / / 15.09.2007
в таблице также закрашиваются поля разным цветом в зависимости от ситуации... и если сделать цикл от 1 до 3000, в котором забивается постоянная строковая константа в ячейку таблицы, то скорость не на много увеливается... Т.е. я создавал пустой проект, создавал цикл, назначал первому столбцу значение и цвет - скорость была около 12 секунд...

PS: я использую TNextGrid от NextSuite (Berg)
3.2K
09 октября 2007 года
nikipelovav
152 / / 12.04.2006
Ты пишешь "в таблице также закрашиваются поля разным цветом в зависимости от ситуации...", а в чём сложность реализовать это в TDBGrid ? Описываешь событие OnDrawCell и всё ;). Ты читал моё сообщение об Accuracer и SQLMemTable ?
490
09 октября 2007 года
frid-karatel
357 / / 15.09.2007
Цитата: nikipelovav
Ты пишешь "в таблице также закрашиваются поля разным цветом в зависимости от ситуации...", а в чём сложность реализовать это в TDBGrid ? Описываешь событие OnDrawCell и всё ;). Ты читал моё сообщение об Accuracer и SQLMemTable ?



Да... буду пробовать... я просто никак не могу понять - разве так много времени уходит на отрисовку строк в таблице? :( Что-то странное...

3.2K
09 октября 2007 года
nikipelovav
152 / / 12.04.2006
Не думаю что дело в "рисовании". Всётаки качни мой проект. В классе окна документа (таблицы) есть метод индивидуального представления ячейки:

 
Код:
// нарисовать ячейку
void __fastcall BWindow::DBGMainDrawCell(TObject *Sender, const TRect &Rect, int DataCol, TColumn *Column, TGridDrawState State)
{
...


в нём ни одна строка. К томуже, процедура прорисовки таблицы вызывается 2 раза при каждом переходе на новую строку! К сожалению, только так удалось получить корректную прорисовку. Но, несмотря на это, как я уже писал, 7200 строк сложного SQL запроса отображаются менее чем за 1 секунду. Уверен разработчики из Borland оптимизировали работу с БД ;)
490
09 октября 2007 года
frid-karatel
357 / / 15.09.2007
Цитата: nikipelovav
Всётаки качни мой проект.

уже дня три назад как качнул ;)... особо не разбирался - копался все в своем коде...

386
10 октября 2007 года
newcss
297 / / 05.04.2005
Самого быстрого результата можно добиться только используя ассемблерные вставки....
Я бы сначала целиком считал файл в оперативку, а после через ассемблерные вставки проводил бы вычисления и изменения инфы....
386
10 октября 2007 года
newcss
297 / / 05.04.2005
Если ничего такого незнаешь.... то самый лучший способ пропустить программу свою Через профайлер. Тот вычислит и выведет критические точки, на которые уходит больше всего времени вычислений, оптимизировав их увеличишь скорость =)
490
10 октября 2007 года
frid-karatel
357 / / 15.09.2007
Цитата: newcss
Если ничего такого незнаешь.... то самый лучший способ пропустить программу свою Через профайлер. Тот вычислит и выведет критические точки, на которые уходит больше всего времени вычислений, оптимизировав их увеличишь скорость =)



А где почитать или скачать этот профайлер? что вообще это такое? (вкратце)

Цитата: newcss
Самого быстрого результата можно добиться только используя ассемблерные вставки....
Я бы сначала целиком считал файл в оперативку, а после через ассемблерные вставки проводил бы вычисления и изменения инфы....



Я использую проекцию на файл, т.е. CreateMapFile... с ним работа производится не так уж и медленно... плюс я убрал AnsiString и т.п. вещи, а также множественные вычисления, да и вообще сократил некоторые операции типа перевода типов из int в char, char в AnsiString и др...

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог