PDA

Просмотр полной версии : [*]Оптимизация кода


Jes
10.04.2008, 21:51
Предлагаю создать довольно интересный топ (имхо) .
Например :
Один выкладывает небольшой(!)(верный) кусок кода (5-6 сток , не больше)
остальные дают советы по оптимизации данного участка (подробно аргументируя) ...
Суть - максимально оптимизировать код не только в сторону быстродействия но и универсальности ...
Цель : Взаимное приобретение опыта , и польза для разела

Например :

Jes: выкладывает код :

if( a == true )
{
c = b;
}

ему отвечают :
удобнее писать по другому <как><почему , для чего> , добавить что-то ... дабы увеличить стабильность / присечь возможные ошибки / и т п

Думаю , 'читателям' было бы довольно интересно как услышать полезные советы , так и самим блеснуть знаниями ...
активные авторы плюсуются +

De-visible
10.04.2008, 21:57
А можно что нить на Делфи?
Я бы тоже поучаствовал!

Jes
10.04.2008, 21:59
Язык - любой
->конечно можно :)

ZaCo
10.04.2008, 23:05
>>Один выкладывает небольшой(!)(верный) кусок кода (5-6 сток , не больше)

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

De-visible
10.04.2008, 23:11
>>Один выкладывает небольшой(!)(верный) кусок кода (5-6 сток , не больше)

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

Можно 20-30строк:)

.Slip
10.04.2008, 23:34
if( a == true )
{
c = b;
}
переменная A хоть как вернёт правду. Если ты этим хотел вернуть именно правду с целого числа, то проще
if (a) {c=b;} - довольно глупая конструкция.

Jes
11.04.2008, 00:14
это пример , я имею ввиду не "оптимизацию общего синтаксиса" а про оптимизацию конкретных приёмов ...

.Slip
11.04.2008, 00:22
>> это пример , я имею ввиду не "оптимизацию общего синтаксиса" а про оптимизацию конкретных приёмов ...
Ну так давай не пример а нормальную задачу:)

nerezus
11.04.2008, 09:27
Оптимизация нужна только там, где она нужна. А это определяется профайлером.

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

KSoniX
11.04.2008, 18:46
вот код

char *host=(char*)malloc(100);
char *buf=(char*)malloc(10);
int port;
GetPrivateProfileStringA("Proxy conf","Host",NULL,host,50,"c:\\proxy.cfg");//из файла читаем хост прокси
GetPrivateProfileStringA("Proxy conf","port",NULL,buf,50,"c:\\proxy.cfg");//из файла читаем порт прокси
port=atoi(buf);//конвертация из чара в инт

он читает из файла proxy.cfg можна ли как нибуть подругому и чтобы работал быстрее если proxy.cfg многа записи

zythar
11.04.2008, 18:57
самые быстрые способмы это имхо системные вызовы. в никсах для чтения есть системный вызов read. аналог в винде - хз

имею ввиду что read в винде не системный вызов кажется

KindEcstasy
11.04.2008, 19:17
Ksonix. У тебя тут нечего оптимизировать по большому счёту разве что только на ассемблер переписать этот кусок. кстати. сейчас нету компилятора сишного. просто хотелось бы посмотреть как он атой в асм переведёт (всмысле мусорности кода). Если руками его написать на асме получиться примерно вотт ак:



push ebx
xor ebx, ebx
a3: lodsb
cmp al, '9'
ja a1
cmp al, '0'
jb err
sub al, '0'
jmp a4
a1: cmp al, 'A'
jb err
cmp al, 'F'
ja a2
sub al, 'A'-10
jmp a4
a2: cmp al, 'a'
jb err
cmp al, 'f'
ja err
sub al, 'a'-10
a4: shl ebx, 4
or bl, al
loop a3
err:
mov eax, ebx
pop ebx
ret


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

короче кому не лень посмотреть код функции атой (сишной) - киньте сюды плиз )

KSoniX
11.04.2008, 19:17
вот как в файле хранится

[proxy conf]
Host=192.168.0.3
port=8080

zythar GetPrivateProfileStringA() функция это и ест системный SDK

KSoniX
11.04.2008, 19:33
вот еже код

printf(buffer,"GET %s HTTP/1.1\r\nHost: %s\r\nProxy-Authorization: Basic %s\r\n\r\n\0",proxies[curprox].host,"database.clamav.net",buf);// хттп запрос

retval=send(sock,buffer,strlen(buffer),0);
FILE *fd=fopen("C:\\Daily.cvd","ab");// файл для записи

//Receive answer and check if connected to other proxy
retval = recv(sock,buffer,512,0);

// находим длину приходящего файла
char *a=strstr(buffer,"Content-Length:");
a+=15;
int len =atoi(a);//длина файла в байтах

a=strstr(buffer,"\r\n\r\n"); //на ходим конец сообщения от прокси
a+=4;
int x=a-buffer;//на чала приходящего файла
if(retval-x!=0)
fwrite(a,sizeof(char),retval-x,fd);// запись первых retval-x байта
len-=retval-x;// уменьшаем длину файла
char* buffer1=(char*)malloc(len+2);

//и запись до конца файла
while(1)
{
retval = recv(sock,buffer1,len,0);
buffer1[retval]='\0';
len-=retval;
int k=fwrite(buffer1,sizeof(char),retval,fd);
if(len<=0)
{
fclose(fd);break;
}
}

а этод код он работает с сокетами и скачивает файл

FoX's
11.04.2008, 20:00
вот код

он читает из файла proxy.cfg можна ли как нибуть подругому и чтобы работал быстрее если proxy.cfg многа записи

-------
DWORD readcfg(char* param, char* bufout,DWORD bufsize){
return GetPrivateProfileStringA("Proxy conf",param,NULL,bufout,bufsize,"c:\\proxy.cfg");
}

и читай...

char buf[256];

readcfg("host",buf,255);
readcfg("port",buf,255);

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

KSoniX
11.04.2008, 20:09
FoX's так еше медленные у меня так и так массив чаров

FoX's
11.04.2008, 20:12
сейчас нету компилятора сишного. просто хотелось бы посмотреть как он атой в асм переведёт (всмысле мусорности кода)
короче кому не лень посмотреть код функции атой (сишной) - киньте сюды плиз )

он импортирует ее из msvcrt.dll. Там примерно тоже самое. Быстрее конечно ее на асме отдельно. +)

desTiny
11.04.2008, 20:19
Если изначально в теме разумное зерно (азарт :) ) прослеживался, то вытекла она в чёрти что...

Forcer
11.04.2008, 20:22
Zaco, nerezus всё четко сказали по теме. Jes, объясни на примере(законченном примере) что ты имеешь ввиду. А так nerezus не так давно в одной теме давал ссылку на статью по оптимизации человека, который чуть ли не жизнь этому посвятил. Очень интересная статья. Вроде в теме про php была. 5-6 строк всё же очень мало. Лучше побольше какие-нибудь исходники публиковать хорошо оформленные, написанные в хорошем стиле. Можно открыть какую-нибудь тему про коммерческое программирование. Думаю на ачате есть люди которым есть что сказать на эту тему. Плюс людям будет интересно узнать что программирование это не только сплоенты и вирусы))

KSoniX
11.04.2008, 20:32
точна я согласен стобой Forcer на 100%

desTiny
11.04.2008, 21:05
Как я понял, Jes предложил что-то типа некоторого развлечения по поводу оптимизации кода.

Предлагаю простую задачку:

var
p, i, n: integer;
...
p := 1;
n := 1000000000;
for i := 1 to n do
p := (p * 11856) mod 1743;
write(p);

Цель - сделать это же за O(log(n))

KindEcstasy
11.04.2008, 22:27
Как понять за O?

desTiny
11.04.2008, 22:44
Как понять за O?
за O(f(n)) - Это значит совершить порядка f(n) операций.
То есть, тот код, что я привёл работает за O(n).

К примеру, матрица n*n полностью заполняется за O(n^2)

PS Даже если количество операций типа n*n*n*0.0001 + 0.0007*n*n + 1000*n - 50000*lg(n), то это всё равно O(n^3)

ZaCo
12.04.2008, 01:42
2desTiny бля, код оптимизировать - это надо тупо знать какие операторы/инструкции чем лучше заменять, вообще говоря оптимизировать код можно програмно. на это способен и gcc и vc и intel'овский компилятор. на программиста должна ложиться по большей части задача оптимизации алгоритма и на самом деле все.. тк все остальное даст лишь сомнительный прирост производительности. личный опыт.

зы пример что ты дал слава богу хоть как-то на это похож. для новичков - http://algolist.manual.ru/maths/count_fast/fast_exp.php :


long powmod(long a, long k, long n)
{
long b=1;

while (k) {
if (k%2==0) {
k /= 2;
a = (a*a)%n;
}
else {
k--;
b = (b*a)%n;
}
}
return b;
}

int main()
{
return powmod(11856, n, 1743);
}

KSoniX
12.04.2008, 12:22
я все нашел функцию WideCharToMultiByte() если у каго есть еше варианты давайте :)

nerezus
12.04.2008, 12:57
void CString2Char(CString src,char* ch)
Стандартный метод GetBuffer(0) отлично пашет. Нечего придумывать ;)

KSoniX
12.04.2008, 14:00
nerezus GetBuffer(0) возвращает TCHAR а мне нужна ЧАР
а если я в функции вместо CString поставлю TCHAR

void CString2Char(TCHAR *src,char* ch)
//и
//.........................
for(i=0;i<wcslen(src);i++)
//...............................

вот с этим как?

KSoniX
14.04.2008, 15:43
вот кусок года здес у меня ест 2 edit box в одном логин в другом пасс. я логин и пасс шифрую и записываю в файл но мой шифровальный алгоритм работает с char`ми и я с TCHAR в char конвертирую с помощью функции указанный чуть выше и я шифрую функций fmt_base64() ниже функция шифрования у меня все работает нормальна

//...................

CString logBuff,passBuff;
CEdit* Log;
CEdit* Pass;
char *buffer,buf,*userpass;

Log = (CEdit*)GetDlgItem(IDC_EDIT1);
Pass = (CEdit*)GetDlgItem(IDC_EDIT2);
Log->GetWindowTextW(logBuff);
Pass->GetWindowTextW(passBuff);


if(wcslen(logBuff)!=0)
{
logBuff+=':'+passBuff;
int len =logBuff.GetLength()+2;
buffer=(char*)malloc(len);
WideCharToMultiByte(CP_ACP,WC_NO_BEST_FIT_CHARS,lo gBuff,50,buffer,50,NULL,NULL);

//...................................



функция шифрование



unsigned int fmt_base64(char *dest, const char *src, unsigned int len)
{
unsigned short bits = 0,temp = 0;
unsigned long written = 0;
unsigned int i;
const char base64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx yz0123456789+/=";


for(i = 0; i < len; i++) {
temp <<= 8;
temp += src[i];
bits += 8;
while(bits > 6) {
dest[written] = base64[((temp >> (bits - 6)) & 63)];
written++;
bits -= 6;
}
}

if(bits) {
temp <<= (6 - bits);
dest[written] = base64[temp & 63];
written++;
}

while(written & 3) {
dest[written] = '=';
written++;
}

return written;
}

nerezus
15.04.2008, 07:14
nerezus GetBuffer(0) возвращает TCHAR а мне нужна ЧАР В настройках проекта укажи кодировку "not using", не поможет?)