1 Востаннє редагувалося cheappi386 (28.02.2017 14:19:02)

Тема: Як пришвидшити роботу коду ?

memset(buf, 0, 16);
printf("%d.%d.%d.%d\n", a,bi,ci,di);
wsprintfA(buf, "%d.%d.%d.%d;", a, bi, ci, di);
out = out + std::string(buf);

Чи то wsprintf ,чи то первантажений "+". Працює занадто повільно.Якщо закоментувати остані дві строчки, то все генеруєтся зі швідкістю блискавки.Чи можно тут якось поліпшити швидкість?

2 Востаннє редагувалося reverse2500 (28.02.2017 14:23:04)

Re: Як пришвидшити роботу коду ?

треба глянути в дізассемблер і отладчик, що б розібратись

3

Re: Як пришвидшити роботу коду ?

Спробуйте не уживати WinAPI, а замість того звичайну wsprintf хвункцію з рантайм бібліотеки.

4

Re: Як пришвидшити роботу коду ?

Спробуйте так:

std::ostringstream stringStream;
  stringStream << a << "." << bi << "." << ci << "." <<di;
  std::string out = stringStream.str();

5

Re: Як пришвидшити роботу коду ?

Якщо вам треба тільки підвищити швидкість - видаліть весь код, це найшвидше рішення. А якщо ще й щоб код щось зробив - то так і пишіть, ми не телепати.

Стосовно гальм

out = out + std::string(buf);

створює тимчасовий об'єкт string, який потім копіюється в out і видаляється. Навіть out+=buf буде швидшим. Звісно, якщо у вас не C++11. Але в будь-якому разі треба профілювати код, навмання не відгадаєш, у чому проблема.

6

Re: Як пришвидшити роботу коду ?

Чи можно тут якось поліпшити швидкість?

А де цей шматок використовується?
Та що то за out такий? Маю на увазі як використовуеться дальніше.

7 Востаннє редагувалося cheappi386 (28.02.2017 21:51:37)

Re: Як пришвидшити роботу коду ?

void BlocksExpand(char *first, char *second,std::string &out)
{
    char buf[16] = "";
    unsigned char a, b, c, d,A,B,C,D;
    strcpy(buf, first);
    strtok(buf, ".");
    a=atoi(buf);
    first += strlen(buf)+1;
    strcpy(buf, first);
    strtok(buf, ".");
    b = atoi(buf);
    first += strlen(buf) + 1;
    strcpy(buf, first);
    strtok(buf, ".");
    c = atoi(buf);
    first += strlen(buf) + 1;
    d = atoi(first);

    strcpy(buf, second);
    strtok(buf, ".");
    A = atoi(buf);
    second += strlen(buf) + 1;
    strcpy(buf, second);
    strtok(buf, ".");
    B = atoi(buf);
    second += strlen(buf) + 1;
    strcpy(buf, second);
    strtok(buf, ".");
    C = atoi(buf);
    second += strlen(buf) + 1;
    D = atoi(second);
    //printf("%d.%d.%d.%d\n%d.%d.%d.%d", a, b, c, d,A,B,C,D);
    for (int bi = b; bi < (B + 1); bi++)
    {
        for (int ci = c; ci < (C + 1); ci++)
        {
            for (int di = d; di < (D + 1); di++)
            {
                memset(buf, 0, 16);
                printf("%d.%d.%d.%d\n", a,bi,ci,di);
                wsprintfA(buf, "%d.%d.%d.%d;", a, bi, ci, di);
                out = out + std::string(buf);
            }
        }
    }
    //printf("total: %d", total);
}

середа розробки VS 2015, тому мабуть там не тільки є С++11, а й щє С++14 Але таки конкатенація стрингу через оператор "+" занадто повільна (((

8

Re: Як пришвидшити роботу коду ?

Уф-ф-ф...
Щось мені підказує що тут треба щось по типу list<string>.
Або якщо це масив IP, то матрицю char (B*C*D)x16
Пересмикування string у потрійному циклі - самісінький мазохізм  :D
А потім ту матрицю вже можна конвертувати у стрічки та віводити кудись.

9

Re: Як пришвидшити роботу коду ?

Ну тобто сказати нам, що ви хочете зробити, ви не можете, я правильно зрозумів? Тему можна закривати?

10

Re: Як пришвидшити роботу коду ?

Vi написав:

Уф-ф-ф...
Щось мені підказує що тут треба щось по типу list<string>.

Цікава ідея, а як потім найшвидше той список в массив символів перетворити?

11

Re: Як пришвидшити роботу коду ?

cheappi386 написав:
void BlocksExpand(char *first, char *second,std::string &out)
{
    char buf[16] = "";
    unsigned char a, b, c, d,A,B,C,D;
    strcpy(buf, first);
    strtok(buf, ".");
    a=atoi(buf);
    first += strlen(buf)+1;
    strcpy(buf, first);
    strtok(buf, ".");
    b = atoi(buf);
    first += strlen(buf) + 1;
    strcpy(buf, first);
    strtok(buf, ".");
    c = atoi(buf);
    first += strlen(buf) + 1;
    d = atoi(first);

    strcpy(buf, second);
    strtok(buf, ".");
    A = atoi(buf);
    second += strlen(buf) + 1;
    strcpy(buf, second);
    strtok(buf, ".");
    B = atoi(buf);
    second += strlen(buf) + 1;
    strcpy(buf, second);
    strtok(buf, ".");
    C = atoi(buf);
    second += strlen(buf) + 1;
    D = atoi(second);
    //printf("%d.%d.%d.%d\n%d.%d.%d.%d", a, b, c, d,A,B,C,D);
    for (int bi = b; bi < (B + 1); bi++)
    {
        for (int ci = c; ci < (C + 1); ci++)
        {
            for (int di = d; di < (D + 1); di++)
            {
                memset(buf, 0, 16);
                printf("%d.%d.%d.%d\n", a,bi,ci,di);
                wsprintfA(buf, "%d.%d.%d.%d;", a, bi, ci, di);
                out = out + std::string(buf);
            }
        }
    }
    //printf("total: %d", total);
}

середа розробки VS 2015, тому мабуть там не тільки є С++11, а й щє С++14 Але таки конкатенація стрингу через оператор "+" занадто повільна (((

Вам краще зрозуміти якою мовою ви намагаєтесь писати - або C або C++. У вас яскравий приклад того як на C++ писати не треба.
Використовуйте STL - не треба винаходити лисапеди там, де це не потрібно.

12 Востаннє редагувалося Torbins (01.03.2017 13:25:49)

Re: Як пришвидшити роботу коду ?

Не знаю як там у плюсах, але у Делфі отакий код:

out = out + std::string(buf);

Означає наступне: виділити шматок пам'яті довжиною як out та std::string(buf) разом узяті, скопіювати туди значення out, а за ним std::string(buf). Вказівник на результат записати в out. Як ви мабуть здогадалися, виділення пам'яті, та копіювання довгих рядків - це доволі довга операція. Якщо у вас поганий менеджер пам'яті, то у вас тут іще фрагментація купи буде на додачу до всього. В більш-менш свіжих версіях Делфі менеджер пам'яті дуже хороший. Якщо він бачить, що якийсь рядок постійно росте, то виділяє під нього на 25% більше пам'яті ніж потрібно. В результаті наступних кілька десятків додавань проходять без виділень пам'яті та копіювань. Нові дані просто дописуються в кінець.
Пропоную вам зробити те саме. У вашому випадку перед початком циклу дуже легко порахувати якої довжини в кінці буде out якщо використати маску типу "999.999.999.999;". Задайте йому потрібну довжину один раз перед циклом, а у циклі просто дописуйте в кінець нові дані, та зсувайте вказівник на той кінець. Якщо після циклу виявиться, що використана не уся довжина рядка, то непотрібне легко відрізати.

13

Re: Як пришвидшити роботу коду ?

Я правильно зрозумів, що тут 5 людей намагаються щось підказувати автору, але ніхто, крім автора, не знає, що цей код має робити?

Подякували: A.N.Onim1

14

Re: Як пришвидшити роботу коду ?

Поки що оптимізуємо сферичного коня у вакуумі під назвою BlocksExpand. Чисто для розминки мізків.

15

Re: Як пришвидшити роботу коду ?

Torbins написав:

Поки що оптимізуємо сферичного коня у вакуумі під назвою BlocksExpand. Чисто для розминки мізків.

Ну ок.

#define BlocksExpand(a,b,c) ;

швидше зможете?

16

Re: Як пришвидшити роботу коду ?

Чітер :)

Подякували: koala, A.N.Onim2