Вопросы и ответы по программированию.

Для тех, кто хочет сделать мир лучше.
Сообщение
Автор
Аватара пользователя
wowks
Майор
Майор
Сообщения: 525
Зарегистрирован: 09.12.2008
Благодарил (а): 67 раз
Поблагодарили: 37 раз

#406 Сообщение 09.06.2015, 14:16

$t@t!c_V()1D
уточняющий вопрос:
нюансы оптимизации самого алгоритма ?

у меня кажись самый быстрый алгоритм
(брал за основу этот http://www.opensource.apple.com/source/ ... D/strlen.c + ускорил через a) register-, b) беззнаковую- переменную)
для проверки длины строки, который всёж уступает встроенному (сижу на CLion с MinGW 3.3(x64) и gcc компилером последней версии 4.8.3) )
код

Код: Выделить всё

#include <stdint.h>

#if (INTPTR_MAX == INT32_MAX)
    #define THIS_IS_32_BIT_ENVIRONMENT
#elif (INTPTR_MAX == INT64_MAX)
    #define THIS_IS_64_BIT_ENVIRONMENT
#else
    #error "Environment not 32 or 64-bit!"
#endif

#define HAS_ZERO_CHAR_INT64(v) 		((((v) - 0x0101010101010101) & ~(v) & 0x8080808080808080) != 0)
#define HAS_NO_ZERO_CHAR_INT64(v)   ((((v) - 0x0101010101010101) & ~(v) & 0x8080808080808080) == 0)

#define HAS_ZERO_CHAR_INT32(v) 		((((v) - 0x01010101) & ~(v) & 0x80808080) != 0)
#define HAS_NO_ZERO_CHAR_INT32(v) 	((((v) - 0x01010101) & ~(v) & 0x80808080) == 0)

#define HAS_ZERO_WCHAR_INT64(v)     ((((v) - 0x0001000100010001) & ~(v) & 0x8000800080008000) != 0)
#define HAS_NO_ZERO_WCHAR_INT64(v)  ((((v) - 0x0001000100010001) & ~(v) & 0x8000800080008000) == 0)


#ifdef THIS_IS_64_BIT_ENVIRONMENT
    #define HAS_ZERO_CHAR_WORD(v)        HAS_ZERO_CHAR_INT64(v)
    #define HAS_NO_ZERO_CHAR_WORD(v)     HAS_NO_ZERO_CHAR_INT64(v)

    #define HAS_ZERO_WCHAR_WORD(v)       HAS_ZERO_WCHAR_INT64(v)
    #define HAS_NO_ZERO_WCHAR_WORD(v)    HAS_NO_ZERO_WCHAR_INT64(v)
#else
    #define HAS_ZERO_CHAR_WORD(v)        HAS_ZERO_CHAR_INT32(v)
    #define HAS_NO_ZERO_CHAR_WORD(v)     HAS_NO_ZERO_CHAR_INT32(v)
#endif

#define PTR_ALIGN_MASK              (sizeof(void *) - 1)
#define PTR_ALIGNED(ptr)            (((uintptr_t)ptr & PTR_ALIGN_MASK) != 0)
#define PTR_NOT_ALIGNED(ptr)        (((uintptr_t)ptr & PTR_ALIGN_MASK) == 0)

size_t __fastcall _strlen( const char * str )
{
#define return_if_zero_char(x) \
	if (ptr[x] == '\0') return (ptr - (uint8_t *)str) + x;

    register uint8_t * ptr;

    for (ptr = (uint8_t *)str; PTR_ALIGNED(ptr); ptr++)
        if (*ptr == '\0') return (ptr - (uint8_t *)str);

    while (HAS_NO_ZERO_CHAR_WORD( *((uintptr_t *)ptr) ))
        ptr += sizeof(uintptr_t);

    return_if_zero_char(0);
    return_if_zero_char(1);
    return_if_zero_char(2);
#ifndef THIS_IS_64_BIT_ENVIRONMENT
    return (ptr - (uint8_t *)str) + 3;
#else
    return_if_zero_char(3);
    return_if_zero_char(4);
    return_if_zero_char(5);
    return_if_zero_char(6);
    return (ptr - (uint8_t *)str) + 7;
#endif
}
или компилятора?

(там вроде как есть параметры командной строки компилятору для оптимизации выходящего машинного кода)

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

Аватара пользователя
Monk
VIP
VIP
Сообщения: 4713
Зарегистрирован: 21.11.2009
Благодарил (а): 418 раз
Поблагодарили: 1053 раза
Контактная информация:

#407 Сообщение 09.06.2015, 17:16

wowks
у меня к тебе сложный вопрос. Ты оптимизируешь ради оптимизации или у тебя есть результаты работы профайлера(или ещё какой хрени, которая явно даст цифры, что именно жрет память\время)?

Я просто как то заморачивался работой простых функций и их оптимизаций, а потом прогнал пару раз с профайлером цикл программы и сразу нашел три здоровенных косяка, жрущих порядка 40% ресурсов (от всех ресурсов, занятых программой). После этого за оптимизацию без профайлера даже не берусь.
«По ночам компьютеры собираются вместе и смеются над людьми, если те делают работу, которую могли бы делать компьютеры» (с) habrahabr
 
[hide_num=64]Изображение
Изображение

Не стоит становиться на одно колено ради девушки, которая ради тебя не готова встать на два. (С)
640K ought to be enough for anybody (с) BG[/hide_num]

Аватара пользователя
wowks
Майор
Майор
Сообщения: 525
Зарегистрирован: 09.12.2008
Благодарил (а): 67 раз
Поблагодарили: 37 раз

#408 Сообщение 09.06.2015, 19:17

Monk
да цель максимальная оптимизация скорости выполнения. Профайлером не пользуюсь. Спасибо за наводку!
касательно памяти: простые функции я не тестировал на прожорливость памяти, т.к. единственная из них которая могла бы жрать много памяти это qsort, который у меня не рекурсивный.
скорость измеряю через цикл т.к. меня интересует не столько скорость самой функцию, а скорость относительно другой (например тот же стандартный strlen)
время выполнения замеряю либо через GetTickCount() либо QueryPerformanceCounter(...) перед циклом скажем в 1000000 итераций и после.
оптимизирую так:
1) алгоритм - самое самое главное (вот например сколько алгоритмов сортировки при этом самый быстрый qsort). Тот-же strlen не на этой станице и на передыдущей - небо и земля
2) использование инлайн функций или кусков кода из макросов (с последними главное не слишком увлекаться в пользу читабельности) чтоб тратить меньше тактов на вызов
3) загонять стековые и локальные переменные в регистры если они часто используются (тоже очень большой прирост в скорости)
4) не использовать знаковые переменные если числа которые будут туда писаться всегда >= 0, тк проц быстрее работает с беззнаковыми числами
5) оптимизация самого компилятора:
..... адресная арифметика например для uint32_t * arr: обращение ко второму uint32_t такое arr[1] быстрее чем явная адресная арифметика
..... раньше я увлекался написание циклов через goto в пользу гибкости, но стандартные циклы while, for быстрее благодаря оптимизации компилятора
6) развёрнутые циклы
7) при необходимости можно для быстоты испльзовать lockup таблицы, как например чаcто делается в том же crc32 а можно и не использовать возвращаясь к первому пункту вот пример:
перевод строки в число здесь http://stackoverflow.com/a/4351484 через деление и lockup таблицу с символами и вот алгоритм который я использую int32_to_str без таблицы и деления (алгоритм нарыл на http://fastcode.sourceforge.net/):
тест скорости

Код: Выделить всё

std::string& itostr(int n, std::string& s)
{
    if(n==0)
    {
        s="0";
        return s;
    }

    int sign = -(n<0);
    unsigned int val = (n^sign)-sign;

    int size;
    if(val>=10000)
    {
        if(val>=10000000)
        {
            if(val>=1000000000)
                size=10;
            else if(val>=100000000)
                size=9;
            else
                size=8;
        }
        else
        {
            if(val>=1000000)
                size=7;
            else if(val>=100000)
                size=6;
            else
                size=5;
        }
    }
    else
    {
        if(val>=100)
        {
            if(val>=1000)
                size=4;
            else
                size=3;
        }
        else
        {
            if(val>=10)
                size=2;
            else
                size=1;
        }
    }
    size -= sign;
    s.resize(size);
    char* c = &s[0];
    if(sign)
        *c='-';

    c += size-1;
    while(val>=100)
    {
        int pos = val % 100;
        val /= 100;
        *(short*)(c-1)=*(short*)(digit_pairs+2*pos);
        c-=2;
    }
    while(val>0)
    {
        *c--='0' + (val % 10);
        val /= 10;
    }
    return s;
}

#include <stdint.h>

#if (INTPTR_MAX == INT32_MAX)
    #define THIS_IS_32_BIT_ENVIRONMENT
#elif (INTPTR_MAX == INT64_MAX)
    #define THIS_IS_64_BIT_ENVIRONMENT
#else
    #error "Environment not 32 or 64-bit!"
#endif

#define _in_
#define _out_

#define MAX_INT32_STR_LEN  11

#define OPPOSITE_SIGN_INT32(v)      ((v + (int32_t)0xFFFFFFFF)         ^ (int32_t)0xFFFFFFFF)


size_t __fastcall int32_to_str( _in_ const int32_t y, _out_ char * str )
{
    register int32_t x = y;
    register size_t r_len;
    register uint8_t num;

    r_len = 0;

    if (x < 0)
    {
        if (x == -2147483648)  // --> (x == INT32_MIN)
        {
        #ifdef THIS_IS_64_BIT_ENVIRONMENT
            *((uint64_t *)str) = *((uint64_t *)"-2147483");
            *((uint16_t *)(str + 8)) = *((uint16_t *)"64");
            *(str + 10) = '8';
        #else
            *((uint32_t *)(str + 0)) = *((uint32_t *)"-214");
            *((uint32_t *)(str + 4)) = *((uint32_t *)"7483");
            *((uint16_t *)(str + 8)) = *((uint16_t *)"64");
            *(str + 10) = '8';
        #endif
            return MAX_INT32_STR_LEN;
        }
        else
        {
            x = OPPOSITE_SIGN_INT32(x);
            *str = '-';
            str++;
            r_len = 1;
        }
    }

    if (x < 10000)
    {
        if (x < 100)
        {
            if (x < 10)
            {
                r_len += 1;
                goto num_9;
            }
            else
            {
                r_len += 2;
                goto num_8;
            }
        }
        else
        {
            if (x < 1000)
            {
                r_len += 3;
                goto num_7;
            }
            else
            {
                r_len += 4;
                goto num_6;
            }
        }
    }
    else
    {
        if (x < 1000000)
        {
            if (x < 100000)
            {
                r_len += 5;
                goto num_5;
            }
            else
            {
                r_len += 6;
                goto num_4;
            }
        }
        else
        {
            if (x < 100000000)
            {
                if (x < 10000000)
                {
                    r_len += 7;
                    goto num_3;
                }
                else
                {
                    r_len += 8;
                    goto num_2;
                }
            }
            else
            {
                if (x < 1000000000)
                {
                    r_len += 9;
                    goto num_1;
                }
                else
                {
                    r_len += 10;
                    goto num_0;
                }
            }
        }
    }

num_0:
    num = '0';
    if (x >= 2000000000) {x -= 2000000000; num += 2;}
    if (x >= 1000000000) {x -= 1000000000; num += 1;}
    *str = num;
    str++;

num_1:
    num = '0';
    if (x >= 800000000) {x -= 800000000; num += 8;}
    if (x >= 400000000) {x -= 400000000; num += 4;}
    if (x >= 200000000) {x -= 200000000; num += 2;}
    if (x >= 100000000) {x -= 100000000; num += 1;}
    *str = num;
    str++;

num_2:
    num = '0';
    if (x >= 80000000) {x -= 80000000; num += 8;}
    if (x >= 40000000) {x -= 40000000; num += 4;}
    if (x >= 20000000) {x -= 20000000; num += 2;}
    if (x >= 10000000) {x -= 10000000; num += 1;}
    *str = num;
    str++;

num_3:
    num = '0';
    if (x >= 8000000) {x -= 8000000; num += 8;}
    if (x >= 4000000) {x -= 4000000; num += 4;}
    if (x >= 2000000) {x -= 2000000; num += 2;}
    if (x >= 1000000) {x -= 1000000; num += 1;}
    *str = num;
    str++;

num_4:
    num = '0';
    if (x >= 800000) {x -= 800000; num += 8;}
    if (x >= 400000) {x -= 400000; num += 4;}
    if (x >= 200000) {x -= 200000; num += 2;}
    if (x >= 100000) {x -= 100000; num += 1;}
    *str = num;
    str++;

num_5:
    num = '0';
    if (x >= 80000) {x -= 80000; num += 8;}
    if (x >= 40000) {x -= 40000; num += 4;}
    if (x >= 20000) {x -= 20000; num += 2;}
    if (x >= 10000) {x -= 10000; num += 1;}
    *str = num;
    str++;

num_6:
    num = '0';
    if (x >= 8000) {x -= 8000; num += 8;}
    if (x >= 4000) {x -= 4000; num += 4;}
    if (x >= 2000) {x -= 2000; num += 2;}
    if (x >= 1000) {x -= 1000; num += 1;}
    *str = num;
    str++;

num_7:
    num = '0';
    if (x >= 800) {x -= 800; num += 8;}
    if (x >= 400) {x -= 400; num += 4;}
    if (x >= 200) {x -= 200; num += 2;}
    if (x >= 100) {x -= 100; num += 1;}
    *str = num;
    str++;

num_8:
    num = '0';
    if (x >= 80) {x -= 80; num += 8;}
    if (x >= 40) {x -= 40; num += 4;}
    if (x >= 20) {x -= 20; num += 2;}
    if (x >= 10) {x -= 10; num += 1;}
    *str = num;
    str++;

num_9:
    *str = (char)('0' + x);

    return r_len;
}



int main() {

    DWORD t = GetTickCount();
    char  str[MAX_INT32_STR_LEN];
    std::string s;
    for (DWORD i = 10000000; i > 0; i--){
        int32_to_str(-123456789, &str[0]);
        //itostr(-123456789, s);
    }
    printf("%u", GetTickCount()-t);

    return 0;
}
результат: int_to_str(...) в два раза быстрее чем itostr(...) благодаря переменным в регистрах, сложению вместо деления, маленькому бинарному поиску в начале для определения количества символов результата и отсутствию цикла

вот и всё что я делаю для оптимизации, ведь если ключевые циклы программы работают максимально быстро и выжимать уже нечего, то и вся программа работает максимально быстро! :)

Аватара пользователя
Pr0Ger
Модератор
Модератор
Сообщения: 1829
Зарегистрирован: 16.01.2009
Благодарил (а): 17 раз
Поблагодарили: 214 раз
Контактная информация:

#409 Сообщение 09.06.2015, 20:32

wowks
Ты занимаешься бесполезной тратой времени. Для оптимизации достаточно просто писать нормальный код который решает твою задачу, и в случае чего уже брать профайлер и искать места которые тормозят.
wowks &raquo; Июнь 9th, 2015, 7:17 pm писал(а): результат: int_to_str(...) в два раза быстрее чем itostr(...) благодаря переменным в регистрах, сложению вместо деления, маленькому бинарному поиску в начале для определения количества символов результата и отсутствию цикла
Наглядный пример того, ты потратил пару дней на то, что в реальной программе даст выигрыш по времени меньший чем погрешность измерения.

К вопросу о функциях стандартной библиотеки: то что ты видишь это скорее всего fallback для какой-то странной архитектуры, в то время как реальная реализация написана на асме причем многократно задрачивалась на тему производительности, взять к примеру тот язык, на котором я пишу каждый день: функция objc_msgSend которая неявно вызывается почти в каждой строке кода написана на асме под все возможные архитектуры, потому что от её производительности реально зависит все.

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

Аватара пользователя
wowks
Майор
Майор
Сообщения: 525
Зарегистрирован: 09.12.2008
Благодарил (а): 67 раз
Поблагодарили: 37 раз

#410 Сообщение 09.06.2015, 22:37

Pr0Ger
я вовсе не оптимизирую всё подряд, вот опять же пример где ни какой оптимизации нет и речи быть не может тк системная функция:
Скрытый текст

Код: Выделить всё

/*  _fopen/_freopen access chars:
        access:
            r - read
            w - write
            a - append (включает в себя r)
            + - craete if not exists

        share_access:
            na - no access
            r - read
            w - write
            d - delete
*/

bool _fopen( const wchar_t * filename, const char * access, const char * share_access, HANDLE * file )
{
    bool ignor_file_existance = false;
    bool mov_to_file_end = false;
    DWORD file_access = 0;
    DWORD file_create_setting = OPEN_EXISTING;
    while (*access != '\0')
    {
        switch (*access)
        {
            case 'r': file_access |= GENERIC_READ;
                break;

            case 'w': file_access |= GENERIC_WRITE;
                break;

            case 'a':
            {
                file_access |= GENERIC_WRITE;
                mov_to_file_end = true;
            }
                break;

            case '+':
                file_create_setting = OPEN_ALWAYS;
                ignor_file_existance = true;
                break;

            default:
                break;
        }
        access++;
    }


    if ( ! ignor_file_existance)
    if ( ! _fexists(filename)) return false;


#define FILE_SHARE_NO_ACCESS 0
    DWORD file_share_access = FILE_SHARE_NO_ACCESS;
    if (share_access != NULL)
        while (*share_access != '\0')
        {
            switch (*share_access)
            {
                case 'n': if (share_access[1] == 'a') break;
                    break;

                case 'r': file_share_access |= FILE_SHARE_READ;
                    break;

                case 'w': file_share_access |= FILE_SHARE_WRITE;
                    break;

                case 'd': file_share_access |= FILE_SHARE_DELETE;
                    break;

                default:
                    break;
            }
            share_access++;
        }


    *file = CreateFileW(filename,
                        file_access,
                        file_share_access,
                        NULL,
                        file_create_setting,
                        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
                        0);
    if (*file == INVALID_HANDLE_VALUE) return false;


    if (mov_to_file_end)
        if ( ! SetEndOfFile(*file)) return false;


    return true;
}
её я написал не потому-что мне не нравится fopen а потому что мне нужно при желании запретить доступ к файлу когда я работаю с ним и мне геморно каждый раз вызывать CreateFile и удобнее написать то что выше, где вызов упрощён.
этим я хочу сказать что заморачиваюсь с оптимизацией только базовых функций которые вызываются часто и много где и их не так уж и много (может порядка пары десятков), которые мне нужны
всё остальное либо работает несколько раз либо 1 раз и там действительно как ты говоришь прирост скости будет для масштаба всей программы на уровне погрешности.

придумал пример:
вот если мне (только по пьяни) захочется посчитать сколько строк исходного кода ос линукс.
я в цикле пробегаю по всем каталогам и поочерёдно считываю текстовый файлы в память. тут оптимизировать почти нечего или нет смысла тк системные вызовы и прирост в скорости будет ничтожен. Далее по каждому файлу уже в памяти пробегаюсь функцией strchr и считаю переходы на новую строку, при этом опуская строки с комментариями и пустые строки.
В итоге ключевая функция это strchr и единственное что нужно оптимизировать для существенного прироста в скорости это её.
Да пример не очень хорош, тк всё будет и без оптимизации довольно таки быстро работать, и больше времени уйдёт на обращение к харду, чем подсчёт строк, но я хотел передать смысл.

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

для всей программы действительно удобен профайлер.

вот я выразил мысль. Прошу меня поправить, если я заблуждаюсь, ведь я учусь с целью писать классный код и потому приму любую критику на свой счёт! :)
Pr0Ger &raquo; Вт июн 09, 2015 6:32 pm писал(а):взять к примеру тот язык, на котором я пишу каждый день
можно узнать что-за язык такой? Мне просто любопытно.

Аватара пользователя
Pr0Ger
Модератор
Модератор
Сообщения: 1829
Зарегистрирован: 16.01.2009
Благодарил (а): 17 раз
Поблагодарили: 214 раз
Контактная информация:

#411 Сообщение 10.06.2015, 11:09

wowks &raquo; Июнь 9th, 2015, 10:37 pm писал(а):вот если мне (только по пьяни) захочется посчитать сколько строк исходного кода ос линукс.
А я сделаю в консоли

Код: Выделить всё

find . | xargs wc -l
и получу тоже самое, но потратив значительно меньше времени. А одна из главных вещей, которую нужно понять, это то что время программиста на порядки дороже машинного времени.
wowks &raquo; Июнь 9th, 2015, 10:37 pm писал(а): её я написал не потому-что мне не нравится fopen а потому что мне нужно при желании запретить доступ к файлу когда я работаю с ним и мне геморно каждый раз вызывать CreateFile и удобнее написать то что выше, где вызов упрощён.
Вот такой подход правильный, у меня в каждом проекте есть всякие Utils, которые просто оборачивают некоторые вызовы, которые делаются всегда с одинаковыми аргументами, типа вот такого:

Код: Выделить всё

- (NSLayoutConstraint *)zz_horizontalCenterInSuperviewConstraint {
    return [NSLayoutConstraint constraintWithItem:self
                                        attribute:NSLayoutAttributeCenterX
                                        relatedBy:NSLayoutRelationEqual
                                           toItem:self.superview
                                        attribute:NSLayoutAttributeCenterX
                                       multiplier:1
                                         constant:0];
}
wowks &raquo; Июнь 9th, 2015, 10:37 pm писал(а):этим я хочу сказать что заморачиваюсь с оптимизацией только базовых функций которые вызываются часто и много где и их не так уж и много
Но вот это вот не правильно: во первых функции стандартной библиотеки писались очень крутыми чуваками, которые понимают очень низкоуровневые нюансы на уровне того как процессор перемалывает внутри себя, которые порой вытекают в том, что на взгляд менее оптимальный код выполняется на железе быстрее, потому что казалось бы оптимальный код на самом деле сводит с ума branch prediction unit и все выполняется медленнее. Во вторых, компилятор знает про существование стандартной библиотеки, понимает её и может применять различные оптимизации исходя из этого знания.
wowks &raquo; Июнь 9th, 2015, 2:16 pm писал(а):gcc компилером последней версии 4.8.3
Это вот кстати тоже, clang понимает код гораздо глубже и делает более оптимальный код
wowks &raquo; Июнь 9th, 2015, 10:37 pm писал(а): те я теряю время сейчас на оптимизацию базовых и самых востребованных функций, которые используются почти в любой программе чтоб в перспективе это самое время (время выполнения) выиграть для всех программ которые надумаю писать.
Суть в том, что поверх него всего написана куча всего, что все равно не будет использовать эти кастомные функции и при этом может работать криво. Так что выигрыш/время ничтожно мал

wowks &raquo; Июнь 9th, 2015, 10:37 pm писал(а): можно узнать что-за язык такой? Мне просто любопытно.
Objective-C, подсказка была в названии функции

MOZGIII
Разработчик
Разработчик
Сообщения: 910
Зарегистрирован: 09.01.2009
Откуда: Переезжаю в /dev/null
Благодарил (а): 7 раз
Поблагодарили: 65 раз
Контактная информация:

#412 Сообщение 13.06.2015, 23:47

wowks
wowks &raquo; 09 июн 2015, 23:37 писал(а):вот если мне (только по пьяни) захочется посчитать сколько строк исходного кода ос линукс.
я в цикле пробегаю по всем каталогам и поочерёдно считываю текстовый файлы в память. тут оптимизировать почти нечего или нет смысла тк системные вызовы и прирост в скорости будет ничтожен. Далее по каждому файлу уже в памяти пробегаюсь функцией strchr и считаю переходы на новую строку, при этом опуская строки с комментариями и пустые строки.
В итоге ключевая функция это strchr и единственное что нужно оптимизировать для существенного прироста в скорости это её.
Да пример не очень хорош, тк всё будет и без оптимизации довольно таки быстро работать, и больше времени уйдёт на обращение к харду, чем подсчёт строк, но я хотел передать смысл.
Конкретно этот пример можно "оптимизировать" засчёт использования теории индуктивных функций.

Вообще, оптимизация кода не так важна, как передача аппаратуре макимально эффективных инструкций. И речь не только о CPU. Начинать, конечо следует как раз с CPU - почитайте про устройство железки. Должно стать примерно понятно, что сколько времени занимает и где.
Но если всё-же вернуться к коду, то его оптимизацией занимается теория суперкомпиляции. Она ещё не совсем готова, но выглядит многообещающе.

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

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

Добавлено спустя 11 минут 51 секунду:
И, да, естественно, профайлер в обычных программах очень помогает. Однако, при его использовании нужно понимать, как он работает (с тем-же железом) и какой оверхед/изменения в поведении он будет вносить. Но с практической точки зрения это очень полезный и нужный интсрумент.

Добавлено спустя 22 минуты 54 секунды:
А ещё, если хотите оптимальные программы - пишите (или хотя бы поразмыслите над тем чтобы писать) их на чём-то получше, чем C. Фишка С в его близости к железу, но это не всегда означает максимальную производительность.

Аватара пользователя
wowks
Майор
Майор
Сообщения: 525
Зарегистрирован: 09.12.2008
Благодарил (а): 67 раз
Поблагодарили: 37 раз

#413 Сообщение 14.06.2015, 12:37

MOZGIII
MOZGIII &raquo; Сб июн 13, 2015 9:13 pm писал(а):теории индуктивных функций.
MOZGIII &raquo; Сб июн 13, 2015 9:13 pm писал(а):теория суперкомпиляции
спасибо за информацию. Очень интересно!

Аватара пользователя
wowks
Майор
Майор
Сообщения: 525
Зарегистрирован: 09.12.2008
Благодарил (а): 67 раз
Поблагодарили: 37 раз

#414 Сообщение 23.09.2015, 13:42

Скажите пожалуйста как получить название Depot-а по его appid
например
1_5409401804038872403.manifest = "Base Goldsrc Shared Content"
96_8007990985538868417.manifest = "Half-Life High Definition"
нашёл такое http://api.steampowered.com/ISteamApps/GetAppList/v2
но там только appid для самих игр

Аватара пользователя
NiGHt-LEshiY
Полковник
Полковник
Сообщения: 10258
Зарегистрирован: 13.06.2008
Откуда: Россия
Благодарил (а): 752 раза
Поблагодарили: 2667 раз
Контактная информация:

#415 Сообщение 25.09.2015, 19:15

wowks
Это название депо по DepotID, а не AppID.
Не знаю как получить пока, не смотрел :(
Кодекс поведения участников сообщества — обязательно к прочтению.
Просьба присылать сообщения об ошибках в ЛС.

Аватара пользователя
wowks
Майор
Майор
Сообщения: 525
Зарегистрирован: 09.12.2008
Благодарил (а): 67 раз
Поблагодарили: 37 раз

#416 Сообщение 26.09.2015, 12:08

NiGHt-LEshiY
NiGHt-LEshiY &raquo; Пт сен 25, 2015 5:15 pm писал(а):Не знаю как получить пока, не смотрел :(
Тогда вот всё, что удалось нарыть по названиям депо:
Есть сайт "steamdb.info".
Согласно словам авторов сайта, они получают эту информацию через "SteamKit"

Я заглянул в SteamKit и вроде нашёл нужный код
https://github.com/SteamRE/SteamKit/blo ... eamApps.cs

В opensteamworks тоже есть заголовочники ISteamApps(001...007).h, в частности AppsCommon.h
правда я не сопоставлял код

в папке "AcfToolkit\Resources\Tools" есть консольная программа "acfv2.exe" и при запуске с параметром "dump" создаётся текстовый файл содержимое которого соответствует, тому что можно получить командой "app_info_print" в консоли Steam

Аватара пользователя
kinders666
Модератор
Модератор
Сообщения: 4163
Зарегистрирован: 25.10.2006
Откуда: Москва
Благодарил (а): 537 раз
Поблагодарили: 191 раз

#417 Сообщение 10.10.2015, 16:07

Нужна помощь по Qt с ООП
Есть форма с огромный количеством QComboBox'ов. Мне нужно проверить их значения. Разобрался, как проверить значение одного бокса, это:

Код: Выделить всё

if (ui -> comboBox1 -> currentText() == "")
Проверка, соответственно, первого бокса
Хочу сделать цикл, но никак не получается, вариант такой:

Код: Выделить всё

QList <QComboBox *> m_ComboList;
for (int i = 0; i < m_ComboList.count(); i++)
{
        if (m_ComboList.at(i) -> currentText() == "")
}
Ошибок не выдаёт, но перестаёт вообще реагировать на if

Добавлено спустя 47 минут 9 секунд:
Вопрос снимается, нужно было:

Код: Выделить всё

QList<QComboBox *> allComboBox = findChildren<QComboBox *>();
    for(int i = 0; i < allComboBox.size(); i++)
    {
       if (allComboBox[i] -> currentText() == "")
       {
       }
    }
Изображение
Изображение

Ответить Вложения 1