Re[8]: История одной оптимизации
От: Дарней Россия  
Дата: 28.10.05 05:18
Оценка:
Здравствуйте, FR, Вы писали:

FR>Так ведь и обратный посыл который тут активно пиарится, "не оптимизируй пока не припрет" тоже неверен. Часто когда припрет оказывается уже поздно.


тоже верно
но таких случаев все-таки меньше. К тому же, это все равно не отменяет правила "сначала проверь, потом оптимизируй"
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Всех излечит, исцелит
добрый Ctrl+Alt+Delete
Re[3]: История одной оптимизации
От: Pavel Dvorkin Россия  
Дата: 28.10.05 05:31
Оценка:
Здравствуйте, eao197, Вы писали:

E>А вообще-то я имел ввиду, что getch из стандартной библиотеки не обязательно будет каждый раз обращаться к OS. Более вероятно (чем лучше библиотека), что getch берет данные из внутреннего буфера, а запрашивает OS только при его опустошении.


Да надо было просто посмотреть исходники CRT. Они не секрет

int __cdecl fgetc ( REG1 FILE *stream)
{
int retval;
_ASSERTE(stream != NULL);
_lock_str(stream);
retval = _getc_lk(stream);
_unlock_str(stream);
return(retval);
}

#define _getc_lk(_stream) (--(_stream)->_cnt >= 0 ? 0xff & *(_stream)->_ptr++ : _filbuf(_stream))

Так что при некоем счетчике потока (буфера в ОП) >=0 берется символ оттуда со сдвигом в буфере, иначе же вызывается некая _filbuf, которая

*int _filbuf(stream) — fill buffer and get first character

а она внутри себя делает

stream->_cnt = _read(_fileno(stream), stream->_base, stream->_bufsiz);

что приводит к ReadFile.

VC6.


>Причем стандартная библиотека может знать об особенностях OS и ее файловой системы, поэтому подчитываться могут блоки оптимального размера (скажем, сразу класстер или сектор). А если мы сами начнем читать данные блоками и не угадаем с размером блока, то ручной буфферизированный ввод будет проигрывать getch.


+1
With best regards
Pavel Dvorkin
Re[4]: История одной оптимизации
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 28.10.05 05:56
Оценка:
Здравствуйте, FR, Вы писали:

FR>Простенький тест


FR>у меня на 7mb файле выдает такие результаты:

FR>

FR>size = 1, time = 2383, sum = 332666720.000000
FR>size = 1, time = 2333, sum = 332666720.000000
FR>size = 1, time = 2334, sum = 332666720.000000
FR>size = 1024, time = 120, sum = 332666720.000000
FR>size = 1024, time = 110, sum = 332666720.000000
FR>size = 1024, time = 130, sum = 332666720.000000


FR>разница в почти 20 раз фигня?


Напомню, что fread(1) и fgetc -- это чуть разные понятия. Что и доказывается простой модификацией примера:
//------------------------------------------------------------------------------

#include <stdio.h>
#include <time.h>

//------------------------------------------------------------------------------

void Test_fgetc()
{
int c;
double sum = 0.0;

clock_t t1 = clock();
if(FILE *file = fopen("test.txt", "rb"))
 {
 while(EOF != (c=fgetc(file)))
  {
   sum += static_cast< char >( c );
  }
  
 fclose(file);
 clock_t t2 = clock();
 printf("size = 1, time = %d, sum = %f\n", t2 - t1, sum); 
 }
}

void Test(size_t size)
{
char *buf = new char[size];
double sum = 0.0;

clock_t t1 = clock();
if(FILE *file = fopen("test.txt", "rb"))
 {
 while(!feof(file))
  {
  size_t count = fread(buf, 1, size, file);
  for(int i = 0; i < count; ++i) sum += buf[i];
  }
  
 fclose(file);
 clock_t t2 = clock();
 printf("size = %d, time = %d, sum = %f\n", size, t2 - t1, sum); 
 }
 
delete [] buf; 
}

int main(int argc, char *argv[])
{
Test(128);
Test(128);
Test(128);

Test(1024);
Test(1024);
Test(1024);

Test_fgetc();
Test_fgetc();
Test_fgetc();

return 0;
}

//------------------------------------------------------------------------------


У меня на файле в 18Mb получается:
size = 128, time = 93, sum = 1096917.000000
size = 128, time = 93, sum = 1096917.000000
size = 128, time = 94, sum = 1096917.000000
size = 1024, time = 94, sum = 1096917.000000
size = 1024, time = 78, sum = 1096917.000000
size = 1024, time = 78, sum = 1096917.000000
size = 1, time = 219, sum = 1096917.000000
size = 1, time = 250, sum = 1096917.000000
size = 1, time = 219, sum = 1096917.000000


Разница осталась, но уже далеко не на порядок.

Хотя результаты сильно зависят от компилятора. Например, Borland C++ 5.6 и Digital Mars C++ 8.42n:
size = 128, time = 218, sum = 1096917.000000
size = 128, time = 250, sum = 1096917.000000
size = 128, time = 188, sum = 1096917.000000
size = 1024, time = 219, sum = 1096917.000000
size = 1024, time = 156, sum = 1096917.000000
size = 1024, time = 219, sum = 1096917.000000
size = 1, time = 2515, sum = 1096917.000000
size = 1, time = 2500, sum = 1096917.000000
size = 1, time = 2516, sum = 1096917.000000


И от операционки. Например GNU C++ 3.2.2 на Slackware 10.0:
size = 128, time = 150000, sum = 1096917.000000
size = 128, time = 150000, sum = 1096917.000000
size = 128, time = 160000, sum = 1096917.000000
size = 1024, time = 130000, sum = 1096917.000000
size = 1024, time = 130000, sum = 1096917.000000
size = 1024, time = 120000, sum = 1096917.000000
size = 1, time = 750000, sum = 1096917.000000
size = 1, time = 750000, sum = 1096917.000000
size = 1, time = 750000, sum = 1096917.000000

(значение time в 1000 раз больше, т.к. под Linux-ом CLOCK_PER_SEC так же больше).
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: История одной оптимизации
От: Pavel Dvorkin Россия  
Дата: 28.10.05 07:01
Оценка: 23 (3)
Здравствуйте, FR, Вы писали:

FR>Простенький тест


А дай-ка и я свой вклад внесу. За основу взял твой, но переделал по сути


#include <stdio.h>
#include <time.h>

//------------------------------------------------------------------------------

void Test( int nRepeat, int nPasses, int nSize)
{
char buf[1024];
double sum = 0.0;
FILE *file = fopen("test.txt", "rb");
clock_t t1 = clock();
for ( int i = 0; i < nRepeat; i++)
{
    fseek(file,0,SEEK_SET);
    for ( int j = 0; j < nPasses; j++)
          size_t count = fread(buf+j, 1, nSize, file);
    for(j = 0; i < 1024; ++i) sum += buf[i];

}
fclose(file);
clock_t t2 = clock();
printf("nSize = %d, time = %d, sum = %f\n", nSize, t2 - t1, sum); 
}

int main(int argc, char *argv[])
{
Test(100000, 1024,1 );

Test(100000, 1, 1024);

return 0;
}


Автоматический буфер — это специально для тех, кто меня упрекает в том. что я могу иметь memory overrun. У них прекрасная возможность появляется еще раз меня упрекнуть, грешно им этой возможности не дать . Проверку, открылся ли файл, убрал по той же причине.

Итак, читается все время один и тот же первый Кбайт файла. nRepeat — цикл для замера времени. nPasses (число проходов цикла) — как нетрудно догадаться, либо 1024(побайтно), либо 1 (Кбайт) Сейчас, конечно, мне скажут — а что будет если иные значения передать ? Не передавайте, очень Вас прошу . Ну а nSize — размер элемента — 1 или 1024.

Еще раз обращаю внимание — весь Кбайт давно в кэше. Обращений к диску здесь вообще не происходит.

Результат (Release, VC6)

nSize = 1, time = 5546, sum = 70936.000000
nSize = 1024, time = 454, sum = 70936.000000

20 раз не получилось, только 12, ну да ладно, хватит и этого

Пойдем дальше. Перепишем это на WinAPI напрямую


void Test( int nRepeat, int nPasses, int nSize)
{
char buf[1024];
double sum = 0.0;
HANDLE hFile = CreateFile("test.txt", GENERIC_READ,0,NULL,OPEN_EXISTING,0,0);
clock_t t1 = clock();
DWORD dwBytes;
for ( int i = 0; i < nRepeat; i++)
{
    SetFilePointer(hFile, 0, 0, FILE_BEGIN);
    for ( int j = 0; j < nPasses; j++)
          ReadFile(hFile,buf+j, nSize, &dwBytes,NULL);
    for(j = 0; i < 1024; ++i) sum += buf[i];

}
CloseHandle(hFile);
clock_t t2 = clock();
printf("nSize = %d, time = %d, sum = %f\n", nSize, t2 - t1, sum); 
}



Эффект чудовищный. Я уж думал, что у меня просто зависло. Проверил — нет. Пошел покурить, вернулся — готово.

nSize = 1, time = 230562, sum = 70936.000000
nSize = 1024, time = 375, sum = 70936.000000

Объяснение.

Для чтения 1024 байт за 1 раз ReadFile несколько эффективнее. fread — штука сложная, ее текст несколько десятков строк занимает. Ей проверить надо, не вышел ли я за границы файла, не пересек ли границу ее внутреннего буфера. А ReadFile — это просто вызов драйвера ФС, тот обнаруживает, что запрос идет с нулевого смещения, размер хороший, ну и копирует мне из кеша 1 Кбайт. Но, в общем, разница не столь уж большая — 375 против 454.

А вот при чтении по 1 байту ReadFile ужасен. На каждый вызов делается переключение в защищенный режим по int 2E, и делается это у меня 100000 * 1024 раз. Неудивительно, что результаты просто устрашающие.

Итог. При буферизованном вводе fread демпфирует эффект чтения по одному байту. В результате получаем в 12 раз хуже, всего лишь . Ну а при небуферизованном вводе (обращения к ОС) имеем проигрыш в 615(!!!!) раз.

Разумеется, надо учесть и то, что при чтении по 1 байту у меня проход по циклу 1024 раза, а при чтении по 1024 байта — всего 1 раз. Но ведь если хотите читать по одному байту , а прочитать 1024 — платите циклом .

В действительности это не очень существенно. Заменим строчку

ReadFile(hFile,buf+j, nSize, &dwBytes,NULL);

на
f(j);

где

void f(int j)
{
j++;
}

(сделать это приходится, иначе оптимизатор вообще выкинет цикл)

nSize = 1, time = 687, sum = 17621.000000
nSize = 1024, time = 125, sum = 17789.000000

Сумма, здесь, конечно, бессмысленная — данные не читались, мусор суммировался. Так что все время уходит именно на ReadFile.

P.S. Честно говоря, знал, что эффект будет до своих опытов, но чтобы такой — не ожидал. Господа, не откажите в просьбе — проверьте код. Может, я ошибку какую-то сделал и не вижу ее ?
With best regards
Pavel Dvorkin
Re: История одной оптимизации
От: bkat  
Дата: 28.10.05 07:19
Оценка: +1 :))
Пора однако этот форум из философского в графоманский переименовывать
Re[5]: История одной оптимизации
От: sch  
Дата: 28.10.05 07:22
Оценка: -1
"McSeem2" <12737@users.rsdn.ru> сообщил/сообщила в новостях следующее: news:1459073@news.rsdn.ru...
> Вообще-то я удивлен такой большой разницей.
Ну это-то и не вызывает удивления, т.к. при чтении по одному байту функция fread() будет вызвана в 1024 раз больше чем при чтении по килобайту. А на вызов функции требуется определенное время -- затолкать параметры в стек, прочитать их, локальные переменные, и проч. и проч. Если есть задача читать по байту -- надо пользоваться getc(), который определен в RTL Visual C++ следующим образом:

#define getc(_stream)     (--(_stream)->_cnt >= 0 \
                ? 0xff & *(_stream)->_ptr++ : _filbuf(_stream))


P.S. И еще, у меня складывается ощущение, что большинству участников данного спора надо перечитать (или прочтитать) K&R. Узнаете очень много нового и интересного про настоящее программирование.
Posted via RSDN NNTP Server 1.9
Re[5]: Исправление
От: Pavel Dvorkin Россия  
Дата: 28.10.05 07:35
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:


PD>P.S. Честно говоря, знал, что эффект будет до своих опытов, но чтобы такой — не ожидал. Господа, не откажите в просьбе — проверьте код. Может, я ошибку какую-то сделал и не вижу ее ?


Точно, сделал. В суммировании. Черт меня угораздил его оставить. Вместо

for(j = 0; i < 1024; ++i) sum += buf[i];

должно быть, конечно

for(j = 0; j < 1024; ++i) sum += buf[j];

Ошибка, конечно, серьезная. Посыпаю голову пеплом . Но на результатах это не очень сказалось — просто цикл выполнился на 1024 раза меньше.

fread

nSize = 1, time = 6031, sum = 7093600000.000000
nSize = 1024, time = 797, sum = 7093600000.000000

ReadFile

nSize = 1, time = 231390, sum = 7093600000.000000
nSize = 1024, time = 750, sum = 7093600000.000000
With best regards
Pavel Dvorkin
Re[6]: История одной оптимизации
От: sch  
Дата: 28.10.05 07:37
Оценка:
Еще одна мелкая тестовая программка.

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

int main() {
 FILE *fp = fopen("test","rb");
 if(fp == 0) {
  fprintf(stderr, "file not found\n");
  return -1;
 }

 DWORD tm1 = timeGetTime();

 int ch;
 unsigned size = 0;
 while(ch = getc(fp), ch != EOF) size++;

 DWORD tm2 = timeGetTime();

 DWORD delta = tm2 - tm1;
 float ratio = float(size) / float(delta);

 printf("size = %u, tm2 - tm1 = %u, ratio = %f\n",
  size, delta, ratio);

 fclose(fp);

 return 0;
}


Вывод для 11-мегабайтового файла: size = 11250929, tm2 — tm1 = 31, ratio = 362933.193548
Вывод для 1,5-гигабайтовго файла: size = 1469875238, tm2 — tm1 = 47812, ratio = 30742.810131

Вывод: нефига выступать коли руки кривые.
Posted via RSDN NNTP Server 1.9
Re[6]: Исправление
От: Pavel Dvorkin Россия  
Дата: 28.10.05 07:39
Оценка:
Тьфу, бог знает что. В программе все исправил как следует, а в сообщении нет. Должно быть

for(j = 0; j < 1024; ++j) sum += buf[j];

Сегодня четвертьфинал олимпиады ACM. Болею за свои команды и голова малость не тем занята
With best regards
Pavel Dvorkin
Re: История одной оптимизации
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.10.05 08:01
Оценка: :)
Разборки и рассказы про кривые руки закончены. Тем, кто хочет высказаться — велкам на moderator@rsdn.ru . Кто не спрятался — я не виноват.
... << RSDN@Home 1.2.0 alpha rev. 617>>
AVK Blog
Re[7]: История одной оптимизации
От: FR  
Дата: 28.10.05 08:06
Оценка: :))
Здравствуйте, sch, Вы писали:

sch>Вывод для 11-мегабайтового файла: size = 11250929, tm2 — tm1 = 31, ratio = 362933.193548

sch>Вывод для 1,5-гигабайтовго файла: size = 1469875238, tm2 — tm1 = 47812, ratio = 30742.810131

sch>Вывод: нефига выступать коли руки кривые.


Я конечно понимаю что у тебя руки такие прямые что уже не гнутся, и что копьютер у тебя очень шустрый, но твой тест у меня только в 1.63 раза быстрее чем fread(1)
Re[8]: История одной оптимизации
От: sch  
Дата: 28.10.05 08:15
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, sch, Вы писали:


sch>>Вывод для 11-мегабайтового файла: size = 11250929, tm2 — tm1 = 31, ratio = 362933.193548

sch>>Вывод для 1,5-гигабайтовго файла: size = 1469875238, tm2 — tm1 = 47812, ratio = 30742.810131

sch>>Вывод: нефига выступать коли руки кривые.


FR>Я конечно понимаю что у тебя руки такие прямые что уже не гнутся, и что копьютер у тебя очень шустрый, но твой тест у меня только в 1.63 раза быстрее чем fread(1)


На некоторых платформах getc() определен не как макрос, а как функция.
Какой компилятор используешь, какая операционная система?
Re[9]: История одной оптимизации
От: FR  
Дата: 28.10.05 08:39
Оценка:
Здравствуйте, sch, Вы писали:

sch>Здравствуйте, FR, Вы писали:


FR>>Здравствуйте, sch, Вы писали:


sch>>>Вывод для 11-мегабайтового файла: size = 11250929, tm2 — tm1 = 31, ratio = 362933.193548

sch>>>Вывод для 1,5-гигабайтовго файла: size = 1469875238, tm2 — tm1 = 47812, ratio = 30742.810131

sch>>>Вывод: нефига выступать коли руки кривые.


FR>>Я конечно понимаю что у тебя руки такие прямые что уже не гнутся, и что копьютер у тебя очень шустрый, но твой тест у меня только в 1.63 раза быстрее чем fread(1)


sch>На некоторых платформах getc() определен не как макрос, а как функция.

sch>Какой компилятор используешь, какая операционная система?

VC7.1 Win2k. Да и не такой и большой вклад дает вызов функции на фоне операций с диском. То что твой первый результат такой шустрый объясняется только тем что твой файл полностью засосало в кеш операционки, реально ты мерял скорость памяти, попробую удали и создай файл заново, скорость упадет на порядок. Да и пожалуйста не кричи больше.
Re[10]: История одной оптимизации
От: sch  
Дата: 28.10.05 08:49
Оценка:
Здравствуйте, FR, Вы писали:

FR>VC7.1 Win2k. Да и не такой и большой вклад дает вызов функции на фоне операций с диском. То что твой первый результат такой шустрый объясняется только тем что твой файл полностью засосало в кеш операционки, реально ты мерял скорость памяти, попробую удали и создай файл заново, скорость упадет на порядок.

У меня та же платформа.
Возможно оптимизатор заинлайнил fread(), так что надо посмотреть.

FR>Да и пожалуйста не кричи больше.

Прошу прощения если это выглядело так, я собственно и не кричал
Re[11]: История одной оптимизации
От: FR  
Дата: 28.10.05 09:03
Оценка:
Здравствуйте, sch, Вы писали:

sch>Здравствуйте, FR, Вы писали:


FR>>VC7.1 Win2k. Да и не такой и большой вклад дает вызов функции на фоне операций с диском. То что твой первый результат такой шустрый объясняется только тем что твой файл полностью засосало в кеш операционки, реально ты мерял скорость памяти, попробую удали и создай файл заново, скорость упадет на порядок.

sch>У меня та же платформа.
sch>Возможно оптимизатор заинлайнил fread(), так что надо посмотреть.

; 17   :   {
; 18   :   size_t count = fread(buf, 1, size, file);

    push    edi
    push    ebp
    push    1
    push    esi
    call    _fread


Просто проверь у себя что быстрее gets или fread(1)
Re[11]: Quod erat demonstrandum
От: sch  
Дата: 28.10.05 09:11
Оценка:
Результаты программы FR на моем компьютере для 11-мегабайтовго файла:
size = 1, filesize = 11250929, time = 312.000000, ratio = 36060.669872
size = 1, filesize = 11250929, time = 297.000000, ratio = 37881.915825
size = 1, filesize = 11250929, time = 312.000000, ratio = 36060.669872
size = 1024, filesize = 11250929, time = 16.000000, ratio = 703183.062500
size = 1024, filesize = 11250929, time = 16.000000, ratio = 703183.062500
size = 1024, filesize = 11250929, time = 15.000000, ratio = 750061.933333


(я модифицировал программу, чтобы она выдавала результаты в тех же единицах и убрал вычисление суммы)

Для 80-мегабайтового файла:
size = 1, filesize = 83275297, time = 2296.000000, ratio = 36269.728659
size = 1, filesize = 83275297, time = 2282.000000, ratio = 36492.242331
size = 1, filesize = 83275297, time = 2281.000000, ratio = 36508.240684
size = 1024, filesize = 83275297, time = 125.000000, ratio = 666202.376000
size = 1024, filesize = 83275297, time = 141.000000, ratio = 590604.943262
size = 1024, filesize = 83275297, time = 125.000000, ratio = 666202.376000


P.S. Компилятор fread() не заинлайнил, хотя заинлайнил _feof().
Re[12]: Quod erat demonstrandum
От: FR  
Дата: 28.10.05 10:44
Оценка:
Здравствуйте, sch, Вы писали:

Да еще vc71 не инлайнит getc:

; 20   :  while(ch = getc(fp), ch != EOF) size++;

    push    edi
    mov    ebp, eax
    xor    esi, esi
    call    _getc
    add    esp, 4
    cmp    eax, -1
    je    SHORT $L55552
    npad    1
$L55551:
    push    edi
    inc    esi
    call    _getc
    add    esp, 4
    cmp    eax, -1
    jne    SHORT $L55551
$L55552:
Re[13]: Quod erat demonstrandum
От: sch  
Дата: 28.10.05 11:15
Оценка:
Здравствуйте, FR, Вы писали:

FR>Да еще vc71 не инлайнит getc:

Это происходит если используется STLport:

Из STLport-овского cstdio:
// undef obsolete macros
# undef putc
# undef getc
# undef getchar
# undef putchar
# undef feof
# undef ferror


C STL из Visual C++ все инлайнится (и в release, и в debug), и G++ тоже инлайнится
в стандартной поставке.

; 7    :     int ch = getc(fp);

  0000f    8b 48 04     mov     ecx, DWORD PTR [eax+4]
  00012    83 c4 08     add     esp, 8
  00015    49         dec     ecx
  00016    89 48 04     mov     DWORD PTR [eax+4], ecx
  00019    78 05         js     SHORT $L708
  0001b    ff 00         inc     DWORD PTR [eax]

; 8    : }

  0001d    33 c0         xor     eax, eax
  0001f    c3         ret     0
$L708:

; 7    :     int ch = getc(fp);

  00020    50         push     eax
  00021    e8 00 00 00 00     call     __filbuf
  00026    83 c4 04     add     esp, 4
Re[14]: Quod erat demonstrandum
От: FR  
Дата: 28.10.05 13:17
Оценка: :)
Здравствуйте, sch, Вы писали:

FR>>Да еще vc71 не инлайнит getc:

sch>Это происходит если используется STLport:

STLPort не использовал.

sch>C STL из Visual C++ все инлайнится (и в release, и в debug), и G++ тоже инлайнится

sch>в стандартной поставке.

У меня только gcc3.4.4 заинлайнил, на быстродействие это практически не отразилось оно точно такое же как и у VC7.1 (который не встраивает).
Re[8]: История одной оптимизации
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.10.05 15:01
Оценка: 14 (3) +4
Здравствуйте, FR, Вы писали:

FR>Так ведь и обратный посыл который тут активно пиарится, "не оптимизируй пока не припрет" тоже неверен. Часто когда припрет оказывается уже поздно.


Все не совсем так. Лично я выступаю за очень простой набор правил:

Разработка

1. Пишем программу так чтобы было не стыдно показать ее код/дизайн другим, и чтобы этот код максимально просто поддавался бы развитию и модификации.
2. Проектируя код задумываемся над тем в каких условиях он должен работать и с какими проблемами можем столкнутся. Исходя из этого выбираем приемлемые алгоритмы и средства (библиотеки, рантаймы, компиляторы и т.п.) и другие проектные и локальные решения.
3. Когда встает выбор того или иного решения, которое может повлиять на производительность смотрим на то насколько это решение ухудшает дизайн приложения и что оно может дать с точки зрения производительности. Если дизайн не ухудшается и не усложняется реализация, то выбираем потенциально более быстрый вариант. При этом, если это не сложно, имеет смысл проверить свои предположения на практике (сделать тест). Проверяя предположение не забываем о том, что полученные результаты могут зависеть от локальных условий (например, процессора или драйвера видеокарты). Если же дизайн усложняется, то плюем на оптимизацию до того момента пока не сможем проверить влияние этого решения. Попутно записываем в список TODO требование проверить, это предположение.
4. Тестируем приложение на максимально широком списке девайсов и в максимально разнообразных условиях.
5. Если есть нарекания пользователей, начинаем заниматься оптимизациями которые могут ухудшить дизайн приложения.

Оптимизация

1. Собираем список нареканий пользователей.
2. Производим собственное тестирование с привлечением профайлеров и т.п.
3. Определяем приоритеты оптимизации и возможное ее влияние на дизайн (расширяемость и поддерживаемость) программы.
4. Эмулируем ситуацию в более простом окружении, чтобы изолировать ее от возможных побочных воздействий. Проверяем, что изолированный вариант повторяет ситуацию с тормозами. Если этот пункт не выполним (например, очень трудоемок), то стараемся создать тест, демонстрирующий проблему.
5. Выносим окончательное суждение о причине проблем.
6. Находим другое решение и думаем, как оно влияет на дизайн программы.
7. Проверяем решение на тесте.
8. Модифицируем программу пытаясь минимизировать вредное влияние оптимизации.
9. Снова тестируем чтобы убедиться что проблема устранена.
10. Если есть другие проблемы, переходим к пункту 1 этого списка и начинаем решать их.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.