Optimalizácia programového kódu. Hlavné vlastnosti optimalizácie kódu programátorom a kompilátorom

Niekedy môže byť ťažké rozhodnúť sa, ktorá konštrukcia je lepšie použiť i++ alebo ++i, alebo si vybrať medzi if-else a switch. Tento článok, napísaný špeciálne pre komunitu IT Works, predstavuje tie najreálnejšie nástroje na optimalizáciu kódu, ktoré by mal poznať každý profesionálny programátor.

Niektorí ľudia si myslia, že časy optimalizácie na úrovni kódu sú nenávratne preč, ale to nie je pravda. Teraz existuje veľa platforiem, v ktorých nie sú také výkonné kompilátory ako v Microsoft Visualštúdio. Napríklad jazyky shaderov (hlsl, glsl) alebo kód pre CUDA, PlayStation3, SPU alebo mobilné platformy. V závislosti od organizácie kódu sa jeho účinnosť môže desaťnásobne líšiť, niekedy kvôli neefektívnosti kompilátora, ale častejšie kvôli prístupu do pamäte.

Pri programovaní pre rôzne platformy si preštudujte možnosti vášho kompilátora a vlastnosti architektúry procesora (ak píšete pre konkrétnu konzolu). Vykonajte výkonnostné testy rôznych možností optimalizácie. Často je ťažké odhadnúť, ktoré metódy budú najúčinnejšie. A tento článok vám prezradí rôzne triky, ktoré vám môžu pomôcť. Nemali by ste však optimalizovať naslepo, bez predchádzajúcej analýzy a profilovania. Pamätajte, že predčasná optimalizácia je zlo.

Ak ste programátor vo VS pod Windows, potom si kompilátor s najväčšou pravdepodobnosťou efektívne poradí s mnohými opísanými optimalizačnými technikami. Venujte pozornosť bodom práce s pamäťou a tiež vám odporúčam, aby ste sa oboznámili s technikou dátovo orientovaný dizajn. V článku nájdete niekoľko tipov na jeho použitie.

Takže začnime:

1. Použite vektorizáciu údajov a inštrukcie na spracovanie vektorov (napríklad SSE v CPU alebo dátovom balíku, ak používate shadery alebo CUDA). To umožní použitie architektúry SIMD (Single Instruction, Multiple Data), čo výrazne zvýši rýchlosť výpočtov. Ak sa rozhodnete použiť túto metódu, potom nezabudnite na zarovnanie údajov v pamäti.

2. Je efektívnejšie sčítať a množiť v mixe, ako najprv všetko sčítať a potom všetko násobiť. Je to preto, že sčítanie a násobenie vykonávajú rôzne moduly procesora a môžu sa vykonávať súčasne.
int a,b,c,k,m,n,t,fl,f2,f3,g1,g2,g3; a = b + c; k = m + n; t = a + k; f1 = f2 * f3; g1 = g2 * g3; Menej účinné ako: a = b + c; f1 = f2 * f3; k = m + n; g1 = g2 * g3; t = a + k;

3. Nie je rozdiel v rýchlosti pri práci s plavákom a dvojnásobnej pri sčítaní a násobení. Vykonávajú sa v rovnakom počte cyklov procesora a používajú rovnaké registre. Pri delení a odbere koreňa je float rýchlejší. Ak však používate veľké množstvo údajov, potom kvôli vyrovnávacej pamäti typ, ktorý zaberá menej pamäte(t.j. plavák), takže vo všeobecnosti je vhodnejšie ho použiť. Voľba double má zmysel, keď je potrebná väčšia presnosť.

4.
Poďme jesť. const float a = 100,0f; float some1 = some3 * 1,0f/a; float some2 = some4 * 1,0f/a; je efektívnejšie písať nie: const float a_inv = 1.0f / a; some1 = some3 * a_inv; some2 = some4 * a_inv; a tak: some1 = some3 * (1.0f / a); some2 = some4 * (1,0f/a); Prečo by to bolo efektívnejšie? Operátory s rovnakou prioritou sa vykonávajú postupne. To znamená, že najskôr sa vykoná násobenie a potom delenie. Ak operáciu delenia orámujete v zátvorkách, kompilátor ju vykoná a v reálnom čase sa vykoná iba operácia násobenia. Čo sa týka rozdielov medzi možnosťou 3 a možnosťou 2, v 3. možnosti sa dodatočná premenná nevytvára, netreba pri pohľade na kód premýšľať, čo to je za premennú. A účinnosť 2. a 3. možnosti bude rovnaká.

5. Pri veľkom množstve údajov a výpočtov na nich je float výnosnejší ako dvojnásobok (kvôli chýbajúcim vyrovnávacím pamäťám, pozri bod 3).

6.
a, b - ľubovoľný výraz Func1, Func2 - funkcie, ktoré budú volané na výpočet podmienky if(a && b) - treba nastaviť prvú menej pravdepodobnú podmienku, pre väčšiu efektivitu if(a || b) - treba najprv nastavte najpravdepodobnejšiu podmienku, aby ste dosiahli efektívnejšie if(Func1() && Func2()) – musíte dať rýchlejší operátor ako prvý

7.
void Func(int* a) ( int b = 10; Nasledujúce riadky sú rovnako efektívne (z hľadiska času vykonania): b = 100; *a = 100; ) Stáva sa to preto, že k premennej zásobníka pristupuje ukazovateľ zásobníka. Existuje aj dereferencia ukazovateľa.

8. Ak existuje veľké pole štruktúr, potom je potrebné, aby sa veľkosť jeho prvkov rovnala mocnine dvoch. Potom bude prechod cez takéto pole oveľa rýchlejší (4-6 krát), kvôli zarovnaniu ukazovateľa ku každej štruktúre v poli.

9.
int a[ 1000]; for(int i =0; i<1000; ++i) a[ i ] = 50; Значительно эффективнее будет: int* p = a; for(int i =0; i<1000; ++i, ++p) *p = 50;

10.
SomeClass*p; - ukazovateľ na pole prvkov x = *(p++); - oveľa efektívnejšie x = *(++p); Z rovnakého dôvodu ako v bode 1. V prvom prípade bude ukazovateľ dereferencovaný a inkrementovaný paralelne a v druhom prípade postupne.

11. Počet stĺpcov dvojrozmerného poľa by sa mal prednostne rovnať mocnine dvoch. Tým sa zvýši rýchlosť práce s poľom. Tým sa zarovnajú ukazovatele na prvé prvky každého riadku, čo urýchli prístup k prvkom.
int mas[ 10 ][ 16 - počet stĺpcov by mal byť prednostne mocninou dvoch]

12.
u32a; f32b; b = (f32)(i32)a; - rýchlejšie b = (f32)a;

13. Vyhnite sa typovému odlievaniu.
plavák f; int a; float b = (float)a; - dlhé int m = (int)f; - veľmi dlho

14. Operácie zaokrúhľovania používajte rozumne:
len pre nepodpísané: (u32)x sú 10-krát rýchlejšie ako „u32(poschodie(x))“ u32(x + 1.0f) sú 10-krát rýchlejšie ako „u32(bunka(x))“ u32(x + 0.5f) sú 10x rýchlejšie ako "u32(round(x))"
15.
float f = 1,0f; *(int*)&f ^= 0x80000000; - rýchlejšie ako f *= -1,0f;

16. Ak sa v prepínači používajú sekvenčné hodnoty parametrov prípadu (prípad 0: prípad 1: prípad 2:...), potom je prepínač oveľa efektívnejší ako if-else. Je to spôsobené tým, že s if-else sa vypočíta hodnota každej podmienky a v prípade takýchto parametrov v konštrukcii prepínača sa hodnota vypočíta raz a potom dôjde okamžite k prechodu na požadovanú hodnotu. položka.

17. Vetvenie je zlo. Pokúste sa znížiť ich počet. Nerobte ich vo veľkých slučkách. prepínač je tiež vetva. Procesor sa snaží predpovedať výsledok podmienky (predikcia vetvenia) a ak je hodnota výrazu takmer vždy rovnaká, tak vetvenie neovplyvní rýchlosť vykonávania kódu. Vo všeobecnosti však bude predpoveď vetvenia nesprávna v 50% prípadov, čo spomalí algoritmus. Každá vetva je prechodom na postupnosť inštrukcií procesora. Takýto prechod prerušuje proces inštrukcií a je dosť drahý.

To platí najmä pre shadery, podprogramy SPU, podprogramy CUDA a v algoritmoch, kde sa spracováva veľké množstvo údajov. Ak potrebujete vykonať nejaký kód pre stotisíc častíc, skúste minimalizovať počet vetiev. To môže výrazne urýchliť vykonávanie kódu.

Const int NN = 12500000; const int N = 10; nasledovné je zlé (200 ms na mojom počítači): for(int i = 0; i< NN; ++i) { switch(i % N) { case 0: res += 10; break; case 3: res += 30; break; case 5: res += 50; break; case 6: res += 60; break; case 8: res += 80; break; } } гораздо лучше (120 ms на моей машине): const int arr = { 10, 0, 0, 30, 0, 50, 60, 0, 80, 0 }; for(int i = 0; i < NN; ++i) res += arr[ i % N ];

18. Uvažujme o príklade. 2D sprite obsahuje pole vrcholov[ 4 ]. Oveľa efektívnejšie by bolo urobiť jedno úložisko vrcholov a v sprite index ofsetu vzhľadom na prvý prvok.
To ušetrí 16 bajtov pre každý sprite z hľadiska pamäte a z hľadiska rýchlosti bude o 30 percent rýchlejší prechod cez vrcholy. Toto je dátovo orientovaný dizajn. To isté platí pre C#.

Hlavné oblasti optimalizácie:
1. Zníženie počtu pobočiek
2. Zoskupovanie údajov podľa rovnakých typov v pamäti (v C# ešte nikto nezrušil polia štruktúr)
3. Zmenšenie veľkosti štruktúr

19.inline funkcie:
+ zvyšuje rýchlosť
- zvyšuje kód
- pri kompilácii pridáva do kódu závislosti (súbory *.h). To zvyšuje čas a objem kompilácie pri zmene kódu vo funkcii

údaje:
1. kompilátor nemusí vložiť funkciu (dokonca aj _forceinlie - neexistuje žiadna záruka vloženia)
2. Keď je povolená optimalizácia rýchlosti, kompilátor VS vkladá všetky funkcie podľa vlastného uváženia, aj keď nie sú deklarované ako vložené.

Záver: Mali by ste sa vyhnúť používaniu inline funkcií. Teraz to už nie je potrebné. Výnimkou môže byť len veľmi často vykonávaný nízkoúrovňový kód (napríklad matematické funkcie) alebo ak program napíšete pomocou kompilátora bez plnej optimalizácie kódu (napríklad použitie inline pre kompilátor PlayStation3 je stále relevantné).

20. Zvážte výsledok zmeny poradia premenných v štruktúre.
struct s1 ( short int a; double b; int d; ) sizeof(s1[ 10 ]) == 24 * 10 struct s2 ( double b; int d; short int a; ) sizeof(s1[ 10 ]) == 16 * 10 double x 8 je vždy zarovnané

21. Preskupením miest podmienok pre plávajúcu hodnotu sa zmení súčet:
1e+8f + 1,23456 - 1e+8f == 0, ale 1e+8f - 1e+8f + 1,23456 == 1,23456

22. Binárne vyhľadávanie by sa nemalo používať pri malom počte položiek. Ak je počet prvkov menší ako 40-60 (tento počet sa môže líšiť od implementácie algoritmov, ale je približne v tomto poradí), bude binárne vyhľadávanie pomalšie ako lineárne.

23.
Je to možné takto: bool b; int a = b? x: y; Ale rýchlejšie: int b; (0 - nepravda, -1 - pravda) int a = (x & b) | (y & ~b);

24.
int a, b; 1. int x = (a >= b > 1:0); 2. int x = (a >= b < -1:0); Možno nahradiť: 1. int x = (b - a) >> 31; 2. int x = (b - a) & 0x80000000;

25.
i32 iIndex; Podmienka: if(iIndex< 0 && iIndex >= iSize) Dá sa nahradiť týmto: if((u32)iIndex >= iSize) Podmienka: if(i >= min && i<= max) Можно заменить таким: if((u32)(i-min) <= (u32)max - min)

26. Vyššie bol uvedený príklad, ako možno prepínač zmeniť na statické pole const a pristupovať k nemu indexom. Platí to napríklad pre rtti (identifikácia typu chodu). Ak je prepínač ukazovateľa funkcie definovaný týmto spôsobom, môže byť jeho nahradenie nepretržitým prístupom k požadovanej funkcii mimoriadne užitočné. To isté platí, ak ide o štátny automat. Namiesto pridania nového prvku do prepínača ho možno pridať do poľa vyššie. Pamätajte však na bod 16.

int func(int index) ( switch(index) ( case 0: return f_Func1(); case 3: return f_Func2(); case 4: return f_Func2(); .. case .. return f_FuncN(): ) return 0; ) nahradiť výrazom: int func(int index) ( statické pole funcPtr = ( &f_Func1, NULL, &f_Func2, ... &f_FuncN ) return pole[ index ](); )

Okrem toho

Ďalšie tipy na písanie efektívnejšieho kódu nájdete v článkoch:

Trochu zo smutného: celý náš život je boj s brzdami. A takto to nemôže ísť donekonečna. Je potrebné optimalizovať všetko – od vášho pracoviska až po čas. V tomto článku som uviedol príklady optimalizácie kódu v programovacom jazyku Delphi, ale verte, že tieto rady sa vám môžu hodiť aj v reálnom živote, ak sa nad tým zamyslíte.

1. Takmer všetko sa dá optimalizovať. A aj tam, kde sa vám zdá, že všetko funguje rýchlo, môžete to urobiť ešte rýchlejšie. Je potrebné mať na pamäti, že akýkoľvek problém možno vyriešiť niekoľkými spôsobmi a vašou úlohou je vybrať ten najracionálnejší z nich.

2. Optimalizácia by mala vždy začínať slabými miestami v programovom kóde. Zvyčajne nie je potrebné optimalizovať niečo, čo funguje tak rýchlo. A efekt takejto optimalizácie bude minimálny.

3. Pri optimalizácii musíte analyzovať všetky operácie, každého operátora, bez toho, aby vám niečo uniklo. Zvyčajne sa optimalizácia začína od tých miest v kóde, kde sa pravidelne opakujú operácie, cykly. To, čo je v slučke, sa bude opakovať n-krát, takže čím menej kódu je v slučke, tým rýchlejšie to procesor vypočíta. Ak sa ukáže, že cyklus je príliš veľký, môže sa rozložiť na niekoľko menších. V tomto prípade sa veľkosť nášho programu zvýši, ale rýchlosť sa zvýši.

4. Skúste použiť menej výpočtov s pohyblivou rádovou čiarkou. Akékoľvek operácie s celými číslami sa vykonávajú rádovo rýchlejšie. Operácie násobenia alebo delenia tiež trvajú dlho. Namiesto násobenia je lepšie použiť sčítanie a delenie možno nahradiť posunom. Posun je oveľa rýchlejší ako násobenie aj delenie. Je to preto, že všetky čísla sú uložené v binárnom systéme. Ak prevediete číslo z desiatkového na binárne a posuniete číslo doprava o jednu pozíciu, všimnete si, že táto operácia je podobná deleniu číslom 2. Pri posune doľava sa číslo delí číslom 2. Hoci tieto operácie sú podobne, posun funguje niekoľkonásobne rýchlejšie.

5. Pri tvorbe procedúr ich nezaťažujte veľkým množstvom vstupných parametrov. A to všetko preto, že pri každom volaní procedúry sa jej parametre zvýšia do špeciálnej oblasti pamäte, zásobníka, a po ukončení sa odtiaľ odstránia. Tiež je potrebné konať opatrne a so samotnými parametrami. Nie je potrebné posielať do procedúr premenné obsahujúce údaje veľkého objemu v čistej forme. Je lepšie odovzdať adresu pamäťovej bunky, kde sú dáta uložené, a v rámci procedúry už s touto adresou pracovať.

6. V najkritickejších momentoch programu, ako je výstup na obrazovku, môžete použiť jazyk Assembler. Dokonca aj vstavaný assembler Delphi je oveľa rýchlejší ako funkcie v rodnom jazyku. Assembler kód môže byť vložený do samostatného modulu, skompilovaný a pripojený k vášmu programu.

7. Neexistujú žiadne zbytočné kontroly. Nemyslite si, že ak nemáte nejakú neštandardnú situáciu, nevznikne to ani pre používateľa. Vždy overte, čo používateľ zadá, bez toho, aby ste čakali na potrebný vstup.

8. Ak píšete dosť veľký a ťažkopádny program, pridajte k nemu komentáre. Kompilátor ich stále ignoruje. A ak zrazu chcete predať zdrojové kódy svojich programov, komentáre zvýšia ich cenu a vy sa v nich budete ľahšie orientovať.

9. Aby ste dosiahli dobrý efekt, musíte poznať IDE, integrované vývojárske prostredie, jazyk, v ktorom programujete, v našom prípade Delphi. Možnosti IDE vám zvyčajne umožňujú vybrať si rôzne typy kompilátorov a predvolená hodnota je najjednoduchšia, najrýchlejšia kompilácia, ktorá však vytvára menej optimalizovaný kód. Preto vždy zaraďte najviac optimalizujúci typ kompilátora.

10. Snažte sa, aby programy mali štandardné rozhranie. Nie je potrebné vytvárať trojuholníkové tlačidlá, neštandardné menu a iné grafické zvončeky a píšťalky. To všetko výrazne spomaľuje program, spotrebúva veľké množstvo počítačových zdrojov a vyžaduje si ďalší čas na vývoj. Napríklad skutočný UNIX je vo všeobecnosti obyčajný shell - riadok na zadávanie príkazov.

To je ako všetko. Prajem vám veľa šťastia pri písaní vašich programov, stačí sa držať týchto rád a uspejete.

A zlepšiť efektivitu. Ciele optimalizácie zahŕňajú zníženie množstva kódu, množstvo pamäte RAM používanej programom, zrýchlenie programu a zníženie počtu I/O operácií.

Hlavnou požiadavkou, ktorá sa zvyčajne kladie na metódu optimalizácie, je, že optimalizovaný program musí mať rovnaký výsledok a vedľajšie účinky na rovnakú množinu vstupných údajov ako neoptimalizovaný program. Táto požiadavka však nemusí zohrávať osobitnú úlohu, ak zisk z použitia optimalizácie možno považovať za dôležitejší ako dôsledky zmeny správania programu.

Typy optimalizácie

Optimalizáciu kódu je možné vykonávať manuálne, programátorom aj automaticky. V druhom prípade môže byť optimalizátorom buď samostatný softvérový nástroj alebo zabudovaný do kompilátora (tzv. optimalizačný kompilátor). Okrem toho je potrebné poznamenať, že moderné procesory dokážu optimalizovať poradie, v ktorom sa kódové inštrukcie vykonávajú.

Existujú také pojmy ako optimalizácia na vysokej a nízkej úrovni. Optimalizácie na vysokej úrovni väčšinou vykonáva programátor, ktorý pri práci s abstraktnými entitami (funkciami, procedúrami, triedami atď.) a predstavou všeobecného modelu riešenia problému dokáže optimalizovať návrh systému. Ako vysoká úroveň sa zvyčajne označujú aj optimalizácie na úrovni elementárnych štrukturálnych blokov zdrojového kódu (slučky, vetvy a pod.); niektorí ich vyčleňujú ako samostatnú („strednú“) úroveň (N. Wirth?). Nízkoúrovňová optimalizácia sa vykonáva vo fáze premeny zdrojového kódu na sadu strojových inštrukcií a často táto fáza podlieha automatizácii. Programátori v assembleri sa však domnievajú, že žiadny stroj v tomto neprekoná dobrého programátora (zatiaľ sa všetci zhodujú, že zlý programátor urobí stroje ešte horšími).

Výber oblasti, ktorá sa má optimalizovať

Pri manuálnej optimalizácii kódu nastáva ďalší problém: potrebujete vedieť nielen to, ako optimalizovať, ale aj to, kde ho aplikovať. Zvyčajne v dôsledku rôznych faktorov (pomalé vstupné operácie, rozdiel v rýchlosti ľudského operátora a stroja atď.) iba 10% kódu zaberie až 90% času vykonávania (samozrejme, vyhlásenie je skôr špekulatívny, a má pochybný základ v podobe zákona Pareto však vyzerá u E. Tanenbauma celkom presvedčivo). Keďže na optimalizáciu bude potrebné vynaložiť viac času, namiesto snahy o optimalizáciu celého programu by bolo lepšie optimalizovať týchto „kritických“ 10 % času vykonávania. Takýto kus kódu sa nazýva úzke miesto alebo úzke miesto a na jeho určenie sa používajú špeciálne programy - profilery, ktoré umožňujú merať čas rôznych častí programu.

V skutočnosti sa optimalizácia často robí po „chaotickej“ programovacej fáze (zahŕňa veci ako „“, „prídeme na to neskôr“, „aj tak to urobíme“), takže ide o zmes správnych optimalizácia, refaktoring a fixácia: zjednodušenie „fantastických“ konštruktov ako strlen(cesta.c_str()), booleovské podmienky (a.x != 0 && a.x != 0) atď. Profilery sú na takéto optimalizácie sotva vhodné. Na odhalenie takýchto miest však môžete použiť programy – nástroje na vyhľadávanie sémantických chýb na základe hĺbkovej analýzy zdrojového kódu – napokon, ako vidíte na druhom príklade, neefektívny kód môže byť výsledkom chýb (ako napr. preklepy v tomto príklade – s najväčšou pravdepodobnosťou a.x != 0 && a.y != 0). Dobrý rozpozná takýto kód a zobrazí varovnú správu.

Škody a výhody optimalizácií

Takmer so všetkým v programovaní by sa malo zaobchádzať racionálne a optimalizácie nie sú výnimkou. Predpokladá sa, že neskúsený programátor v assembleri zvyčajne píše kód, ktorý je 3-5 krát pomalší ako kód generovaný kompilátorom (Zubkov). Existuje dobre známy výrok o skorých, skôr nízkoúrovňových (ako boj o ďalší operátor alebo premennú) optimalizáciách, formulovaný Knuthom: "Predčasná optimalizácia je koreňom všetkých problémov."

Väčšina ľudí si nesťažuje na optimalizácie vykonávané optimalizátorom a niekedy sú niektoré optimalizácie prakticky štandardné a povinné – napríklad optimalizácia chvostovej rekurzie vo funkčných jazykoch (rekurzia chvosta je konkrétny typ rekurzie, ktorú možno zredukovať forma cyklu).

Malo by sa však chápať, že početné komplexné optimalizácie na úrovni strojového kódu môžu značne spomaliť proces kompilácie. Navyše zisk z nich môže byť extrémne malý v porovnaní s optimalizáciami celkového dizajnu systému (Wirth). Nemali by sme tiež zabúdať, že moderné, syntakticky a sémanticky „vymyslené“ jazyky majú veľa jemností a programátor, ktorý ich nezohľadňuje, môže byť prekvapený dôsledkami optimalizácie.

Zoberme si napríklad jazyk C++ a tzv. Optimalizácia návratovej hodnoty, ktorej podstatou je, že kompilátor nesmie vytvárať kópie dočasného objektu vráteného funkciou. Keďže kompilátor v tomto prípade „preskočí“ kópiu, tento trik sa nazýva aj „Copy elision“. Takže nasledujúci kód:

#include štruktúra C ( C() () C(konšt. C&) ( std::cout<< "A copy was made.\n"; } }; C f() { return C(); } int main() { std::cout << "Hello World!\n"; C obj = f(); }

môže mať niekoľko možností výstupu:

ahoj svet! Bola vytvorená kópia. Bola vytvorená kópia. ahoj svet! Bola vytvorená kópia. ahoj svet!

Je iróniou, že všetky tri možnosti sú legálne, keďže jazykový štandard umožňuje v tomto prípade vynechať volanie konštruktora kopírovania, aj keď má konštruktor vedľajšie účinky (§12.8 Kopírovanie objektov triedy, odsek 15).

Výsledok

Preto nezabudnite optimalizovať kód, ak je to možné, pomocou špecializovaných softvérových nástrojov, ale malo by sa to robiť opatrne a opatrne a niekedy sa pripraviť na prekvapenia zo strany kompilátora.

Štúdio PVS

Bibliografický zoznam

  • E. Tanenbaum. Počítačová architektúra.
  • Wirth N. Stavebné kompilátory.
  • Knut D. The Art of Programming, Volume 1. Basic Algorithms.
  • Zubkov S.V. Assembler pre DOS, Windows a UNIX.
  • Wikipedia. optimalizácia kódu.
  • Wikipedia.

Pri prvotnom vývoji stránky ich majitelia najviac dbajú na jej vonkajšie vnímanie a rýchle spustenie. Bezprostredne alebo niekoľko mesiacov po spustení vyvstáva otázka, ako prilákať ďalších zákazníkov. Po určitom čase sa dizajnér a programátor rozložia do práce na internej optimalizácii stránky, kde sa ukáže, že časť napísaného kódu treba prepísať. Preto si v tomto príspevku povieme o optimalizácii html, css a js kódu stránky pri jej prvotnom vývoji, čo klientovi umožní ušetriť peniaze a vývojárom liezť na nervy.

optimalizácia js a css

Začnime s css a js. Na čo slúži optimalizácia css a js?

Približne 50 % používateľov opustí stránku, ak jej načítanie trvá dlhšie ako 3 sekundy, a s každou ďalšou sekundou konverzia webu klesá o 7 %. Jedným z hodnotiacich faktorov je aj rýchlosť načítania webových stránok.

Prvá vec, ktorú treba začať, je riadiť sa odporúčaniami Google. Kód CSS a js by nemal byť obsiahnutý v html kóde stránky, mal by byť umiestnený v samostatných súboroch. Výnimkou sú malé inline štýly s 1-2 hodnotami. Počet zahrnutých súborov by sa mal čo najviac znížiť, v ideálnom prípade ponechať jeden zahrnutý súbor css a js. Pripojenie js súborov by sa malo presunúť na koniec stránky (pred zobrazením stránky ju musí prehliadač analyzovať a ak deteguje externý skript, musí ho načítať, a to je cyklus operácií navyše, ktorý spomaľuje zobrazenie stránky.

Na urýchlenie načítania súborov js, css a obrázkov je tiež vhodné použiť ukladanie do vyrovnávacej pamäte a kompresiu vo formáte GZIP.

SEO rozloženie webu: optimalizácia html kódu alebo ako to urobiť, aby ste to neskôr nemuseli prerábať

Pre správnu budúcu optimalizáciu html kódu sa pozrime na všetky značky a na to, ako ovplyvňujú SEO.

Blokovať :

- označuje názov stránky, ktorý je umiestnený na karte prehliadača a vo vyhľadávačoch. Najdôležitejší tag z hľadiska ovplyvnenia hodnotenia stránky.</p> <p><description>- umožňuje nastaviť popis stránky, ktorý sa zobrazí vo výsledkoch vyhľadávania pod nadpisom. Má oveľa menší vplyv na hodnotenie, ale pomáha zvyšovať CTR (pomer prekliknutí a zobrazení) stránky. Ak je meta description tag vyplnený, nezaručuje to, že výsledky budú zobrazovať presne to, čo je tam napísané, keďže vyhľadávače môžu popis prevziať z obsahu. Ale predsa len je lepšie nastaviť generovanie tagov a nemyslieť na to, aká časť PS textu sa vezme na popis.</p> <p><keywords>- označuje vyhľadávačom, pre ktoré dopyty príslušnú stránku. Po zavedení tohto tagu dostal veľký vplyv na hodnotenie stránok. Optimalizátori môžu jednoducho propagovať stránku s akýmkoľvek produktom internetového obchodu, napríklad na žiadosť „stiahnite si abstrakt príbehu“ alebo na iné témy, ktoré priviedli na stránku návštevníkov, ale nie zákazníkov. Vplyv tejto značky na propagáciu teraz nie je presne známy a mnohí ľudia ju jednoducho ignorujú, a to aj preto, aby nepoškodili stránku.</p> <p><meta name="robots" content="index/noindex, follow/nofollow">(preberá sa jedna z hodnôt, index alebo noindex, follow alebo nofollow) — zákaz indexovania stránky (noindex) a zákaz indexovania odchádzajúcich odkazov na stránke (nofollow) vyhľadávacími nástrojmi. Hodnoty indexu a sledovania sa používajú v spojení s hodnotami bez indexovania, pretože indexovanie stránok a odkazov je predvolene povolené. Túto značku používajte opatrne, aby ste po chvíli nevideli nulovú návštevnosť z vyhľadávačov.</p> <p><link rel="canonical" href="..." />- umožňuje prepojiť niekoľko obsahovo rovnakých stránok, ale s rôznymi adresami URL, na jednu stránku, aby sa zlepšilo jej hodnotenie. Vo väčšine prípadov sa používa pre dynamické stránky, ktoré obsahujú rovnaký obsah, napríklad triedenie stránok v katalógu produktov alebo pri práci s blogom, kde jeden článok môže byť v rôznych sekciách a mať rôzne adresy URL.</p> <p><link rel="prev" href="..." />A <link rel="next" href="..."/>- značky umožňujú určiť predchádzajúce a nasledujúce stránky pre vyhľadávače na stránkovacích stránkach, ak je materiál rozdelený na niekoľko častí a nachádza sa na rôznych adresách URL.</p> <h3>Blokovať <body> :</h3> <p><h1> - <h6>- nadpisy na stránke. Tag <h1>treba použiť raz, napr <title>označuje hlavný obsah stránky, ale má menší vplyv na hodnotenie v SERP. Spravidla pre internetové obchody v značke <h1>názvy týchto kategórií a produktov sú uvedené na stránkach kategórií a produktov, pre informačné stránky - názov, ktorý bude čitateľa zaujímať, plus, ak je to možné, kľúčové slová.</p> <p>značky <h1> - <h6>musí mať logickú štruktúru. hlavička <h1>obsahujú hlavičky <h2>, v ktorom sú nadpisy <h3>atď. Je vhodné ich použiť len v textovom obsahu stránky (napríklad na rozbitie hlavného obsahu na stránke, nie však pre bloky, ktoré sa zobrazujú na všetkých stránkach webu). Vzhľadom na to, že značka <h1>pomáha zvýšiť hodnotu slov v hodnotení, uzavrieť doň všetok text na stránke a pomocou štýlov ho opraviť tak, aby sa dal čítať, potom to neprinesie žiadnu výhodu, ale len poškodí takúto stránku.</p> <p><strong>, <b>, <em>- navrhnutý tak, aby sa zameral na určité frázy a slová v popise stránky, článku, správ atď. (vrátane zvýšenia dôležitosti týchto slov pri hodnotení). Nemali by ste ich používať na rozloženie tých prvkov stránky, ktoré sa opakujú napríklad na všetkých produktoch. Na tento účel je lepšie použiť css. Hoci nie je s istotou známe, či má vplyv slovo alebo fráza opakujúca sa na všetkých stránkach webu, vo vnútri je napr. <strong>, ale je lepšie používať značky na určený účel. Myslím, že PS to ocení.</p> <p><table>- určené aj primárne na umiestnenie do textového obsahu stránky. Umožňuje urobiť text zaujímavejším na čítanie, čo zvyšuje dôveryhodnosť celej stránky z vyhľadávačov (rovnaký efekt majú aj zoznamy, obrázky, videá).</p> <p><ul>, <li>, <ol>, <dl>, <dd>, <dt>- zoznamy, ktoré sa používajú na vytvorenie menu stránky a v hlavnej časti na stránke na štruktúrovanie textových informácií.</p> <p><img>- obrázky na stránke. Popis obrázka by mal byť umiestnený v atribútoch alt=“...“ a title=“...“, čo pomôže pri hodnotení pri vyhľadávaní obrázkov. Pozícia obrázka vo výsledkoch vyhľadávania je tiež ovplyvnená, ak sa názov súboru obrázka zhoduje s jeho popisom.</p> <p><noindex>- označuje Yandex obsah dokumentu, ktorý nemusí byť indexovaný, napríklad servisné informácie. Musí sa používať veľmi opatrne a v zriedkavých prípadoch.</p> <p><div>- skutočný tag pre rozloženie stránky, neovplyvňuje SEO.</p> <p>Značka na zalomenie textu, ale nie na zmenu umiestnenia blokov. Ale to je skôr pre platnosť rozloženia, a nie pre optimalizáciu. Nemá vplyv na optimalizáciu stránky.</p> <p><p>Určuje textový odsek pre hlavný obsah na lokalite (napríklad články alebo popisy produktov, kategórie v internetovom obchode). Je tiež žiaduce aplikovať hlavne na hlavný obsah jednej stránky.</p> <p>Inline prvok, ktorý nemá žiadny vplyv na SEO. V mnohých prípadoch je užitočné použiť spolu s css v nehlavnom obsahu stránky na nahradenie značiek zvýraznenia a nadpisu.</p> <p><header>- hlavička stránky.</p> <p><footer>päta stránky.</p> <p><a>- tu potrebujeme samostatný článok. A nie sám.</p> <p>Možno som vynechal nejaký tag... ale to znamená, že je menej dôležitý. Taktiež neboli zohľadnené niektoré nové značky html5, ako napr <article> , <aside> , <nav> , <section> .</p> <p>Ak usporiadate html značky tak, ako ovplyvňujú relevantnosť kľúčových slov, potom to vyjde niekde takto: title, h1-h6,strong, description, b, em, p, keywords, ul->li & ol->li.</p> <p>Teraz pre lepšiu prezentáciu skúsme vytvoriť správne optimalizované rozloženie stránky.</p><p> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Názov stránky

  • Kategória 1
  • Kategória 2
    • Kategória 2.1
    • Kategória 2.2
  • Kategória 3

Názov stránky

Hlavný obsah so značkami

-

, , , ,
, .

Bočný blok s ďalšími informáciami.
...


Čo ešte musíte zvážiť pri SEO-rozložení stránky

  • Veľký počet chýb overenia môže mať zlý vplyv na stránku. Nie je vhodné používať prázdne značky a css, js súbory, ktoré nie sú na stránke použité. Čím je kód ľahší, tým ľahšie ho vyhľadávače analyzujú.
  • Nemali by ste používať flash a rámy, ktoré nie sú veľmi priateľské k vyhľadávačom. Vyhľadávače tiež nerozpoznajú text nakreslený pomocou obrázka.
  • Povaha stránky naprieč prehliadačmi ovplyvňuje správanie používateľov a núti ich opustiť stránku bez toho, aby dostali potrebné informácie alebo uskutočnili nákup. V dôsledku toho sa zhoršujú faktory správania, ktoré ovplyvňujú optimalizáciu celej stránky.
  • Prítomnosť mobilnej verzie stránky alebo jej prispôsobivosť sa stala hodnotiacim faktorom a podobne ako kompatibilita medzi prehliadačmi umožňuje znížiť mieru odchodov a zvýšiť konverziu stránky na mobilných zariadeniach. Google začal brať do úvahy prítomnosť mobilnej verzie v roku 2015 (priateľská pre mobilné zariadenia) a Yandex v roku 2016, pričom hodnotiaci algoritmus nazval „Vladivostok“.
  • Hlavný obsah na stránke by mal byť umiestnený v html kóde bližšie k začiatku, takže bude relevantnejší z pohľadu vyhľadávača.
  • Obsah by nemal byť skrytý pomocou display:none .
  • Ak používanie značiek môže zvýšiť dôležitosť kľúčového slova, potom môžete mať negatívny efekt aj vtedy, ak sa niektoré značky prekrývajú, napr.
    1. h1-h6 & silné, b, em
    2. h1-h6 & a href=…
    3. silný, b, em & a href=…

Záver

Pri pohľade na stránky vyhľadávačov môžete vidieť množstvo chýb spojených s rozložením stránky, vrátane chýb overenia. Tu však treba pochopiť, že si kladú úplne iné ciele. Pre stránky, ktorých jedným z hlavných zdrojov návštevnosti sú vyhľadávače, je rozloženie optimalizované pre SEO, a bez ohľadu na to, aké skvelé odkazy odkazujú na stránku, nemôžete snívať o prvých pozíciách bez dobrej optimalizácie kódu.

Optimalizácia kódu je modifikácia programov vykonávaná optimalizačným kompilátorom alebo tlmočníkom s cieľom zlepšiť ich vlastnosti, ako je výkon alebo kompaktnosť, bez zmeny funkčnosti.

Posledné tri slová v tejto definícii sú veľmi dôležité: bez ohľadu na to, ako veľmi optimalizácia zlepšuje vlastnosti programu, musí nevyhnutne zachovať pôvodný význam programu za akýchkoľvek podmienok. Preto sú napríklad v GCC rôzne úrovne optimalizácie
Poďme ďalej: existujú optimalizácie nezávislý od stroja (vysoký stupeň) A závislé od stroja (nízky level). Význam klasifikácie je jasný z názvov, pri strojovo závislých optimalizáciách sa využívajú vlastnosti špecifických architektúr, pri vysokoúrovňových optimalizáciách dochádza k optimalizácii na úrovni štruktúry kódu.

Optimalizácie je možné rozdeliť aj podľa rozsahu ich aplikácie na lokálne (operátor, postupnosť operátorov, základný blok), intraprocedurálne, interprocedurálne, intramodulové a globálne (optimalizácia celého programu, „optimalizácia pri montáži“ , „Optimalizácia času prepojenia“).

Ladenie modulu na identifikáciu logických chýb

Ladenie PS je činnosť zameraná na zisťovanie a opravu chýb v PS pomocou procesov vykonávania jeho programov. Testovanie PS je proces vykonávania svojich programov na určitom súbore údajov, pri ktorom je vopred známy výsledok aplikácie alebo sú známe pravidlá správania sa týchto programov. Zadaný súbor údajov sa volá test alebo jednoducho test. Ladenie teda možno reprezentovať ako opakované opakovanie troch procesov: testovanie, v dôsledku ktorého je možné zistiť prítomnosť chyby v PS, hľadanie miesta chyby v programoch a dokumentácii PS a úpravy programov a dokumentácie za účelom odstránenia zistenej chyby. Inými slovami:

Ladenie = Testovanie + Hľadanie chýb + Úpravy.

V zahraničnej literatúre sa ladenie často chápe len ako proces hľadania a opravy chýb (bez testovania), ktorých prítomnosť sa zisťuje počas testovania. Niekedy sa testovanie a ladenie považujú za synonymá. U nás pod pojem ladenie väčšinou patrí testovanie, preto sa budeme držať zavedenej tradície. Spoločné zváženie týchto procesov v tejto prednáške však robí tento rozpor menej významným. Treba však poznamenať, že testovanie sa používa aj ako súčasť procesu certifikácie PS.



Princípy a typy ladenia softvéru

Úspech ladenia PS je do značnej miery predurčený racionálnou organizáciou testovania. Pri ladení PS sa zisťujú a odstraňujú najmä tie chyby, ktorých prítomnosť v PS sa zistí pri testovaní. Ako už bolo uvedené, testovanie nemôže preukázať správnosť PS, v najlepšom prípade môže preukázať prítomnosť chyby v ňom. Inými slovami, nie je možné zaručiť, že testovaním softvéru pomocou prakticky uskutočniteľného súboru testov je možné zistiť prítomnosť každej chyby prítomnej v softvéri. Preto vznikajú dva problémy. Prvou úlohou je pripraviť takýto súbor testov a aplikovať na ne PS, aby sa v ňom odhalilo čo najviac chýb. Čím dlhšie však proces testovania (a ladenie vo všeobecnosti) pokračuje, tým sú náklady na softvér vyššie. Z toho vyplýva druhá úloha: určiť moment, kedy je ukončené ladenie PS (alebo jeho jednotlivých komponentov). Znakom možnosti ukončenia ladenia je úplnosť pokrytia testami prechádzajúcimi cez PS (t. j. testami, na ktoré sa PS aplikuje) mnohých rôznych situácií, ktoré vznikajú pri vykonávaní programov PS, resp. pomerne zriedkavý prejav chýb v PS v poslednom segmente testovacieho procesu. Ten sa určuje v súlade s požadovaným stupňom spoľahlivosti PS, špecifikovaným v špecifikácii jeho kvality.

Na optimalizáciu testovacej súpravy, t.j. na prípravu takého súboru testov, ktorý by umožnil pre daný počet z nich (alebo pre daný časový interval určený na testovanie) odhaliť väčší počet chýb v PS, je potrebné v prvom rade naplánovať tento súbor vopred a po druhé, použiť racionálnu stratégiu plánovania (navrhovania) testov. Návrh testu môže začať ihneď po ukončení etapy externého popisu PS. Existujú rôzne prístupy k vývoju stratégie návrhu testov, ktoré môžu byť podmienene graficky umiestnené medzi nasledujúce dva extrémne prístupy. Ľavý extrémny prístup spočíva v tom, že testy sú navrhnuté len na základe preštudovania špecifikácií PS (externý popis, popis architektúry a špecifikácia modulu). Nie je nijako zohľadnená štruktúra modulov, t.j. zaobchádza sa s nimi ako s čiernymi skrinkami. V skutočnosti si tento prístup vyžaduje úplné vymenovanie všetkých súborov vstupných údajov, pretože v opačnom prípade niektoré časti programov PS nemusia fungovať, ak sa preskočí ktorýkoľvek test, čo znamená, že chyby v nich obsiahnuté sa neobjavia. Testovanie PS s úplným súborom vstupných dát je však prakticky nemožné. Správny extrémny prístup je, že testy sú navrhnuté na základe štúdia textov programov, aby sa otestovali všetky spôsoby, akými sa každý program PS vykonáva. Ak vezmeme do úvahy prítomnosť cyklov s premenlivým počtom opakovaní v programoch, potom môže existovať aj extrémne veľké množstvo rôznych spôsobov vykonávania PS programov, takže ich testovanie bude tiež prakticky nemožné.

Jednotkové testovanie

Každý komplexný softvérový systém sa skladá zo samostatných častí – modulov, ktoré ako súčasť systému plnia určitú funkciu. Aby ste si overili správnu činnosť systému ako celku, musíte najskôr otestovať každý modul systému samostatne. V prípade problémov to uľahčí identifikáciu modulov, ktoré spôsobili problém, a odstránenie zodpovedajúcich chýb v nich. Toto testovanie modulov jednotlivo sa nazýva testovanie jednotiek ( jednotkové testovanie).

Pre každý testovaný modul je vyvinuté testovacie prostredie, ktoré obsahuje ovládač a stub, testovacie požiadavky a testovacie plány, ktoré popisujú špecifické testovacie prípady.

Hlavným účelom testovania jednotiek je overiť, či každý jednotlivý modul systému spĺňa požiadavky pred jeho integráciou do systému.

Zároveň sa počas testovania jednotiek riešia štyri hlavné úlohy.

1. Hľadanie a dokumentovanie nezhôd- Ide o klasickú testovaciu úlohu, ktorá zahŕňa nielen vývoj testovacieho prostredia a testovacích prípadov, ale aj vykonávanie testov, zaznamenávanie výsledkov vykonávania a hlásenie problémov.

2. Podpora vývoja a refaktoringu nízkoúrovňovej architektúry systému a medzimodulovej komunikácie- táto úloha je charakteristickejšia pre "light" metodiky ako XP, kde sa uplatňuje princíp testovania pred vývojom (Test-driven development), v ktorom hlavným zdrojom požiadaviek na softvérový modul je test napísaný pred samotným modulom. Avšak aj pri klasickej testovacej schéme môžu unit testy odhaliť problémy v návrhu systému a nelogické alebo mätúce mechanizmy práce s modulom.

3. Podpora refaktorovania modulov- Táto úloha súvisí s podporou procesu zmeny systému. Pomerne často sa pri vývoji vyžaduje refaktorovanie modulov alebo ich skupín – optimalizácia alebo kompletný redizajn programového kódu s cieľom zvýšiť jeho udržiavateľnosť, rýchlosť či spoľahlivosť. Unit testy sú však mocným nástrojom na overenie, či nová verzia programového kódu funguje úplne rovnako ako tá stará.

4. Podpora riešenia problémov a ladenia- Táto úloha je spojená so spätnou väzbou, ktorú vývojári dostávajú od testerov vo forme hlásení o problémoch. Podrobné hlásenia o problémoch zostavené počas fázy testovania jednotky umožňujú lokalizovať a eliminovať mnohé chyby v softvérovom systéme v počiatočných fázach jeho vývoja alebo vývoja jeho novej funkcionality.

Vzhľadom na to, že testované moduly majú zvyčajne malú veľkosť, jednotkové testovanie sa považuje za najjednoduchšiu (aj keď pomerne časovo náročnú) fázu testovania systému. Napriek zjavnej jednoduchosti však pri testovaní jednotiek existujú dva problémy.

1. Neexistujú jednotné zásady na určenie toho, čo presne je samostatný modul.

2. Rozdiely vo výklade samotného pojmu unit testing - či už ide o samostatné testovanie modulu, ktorého činnosť podporuje iba testovacie prostredie, alebo či ide o kontrolu správnosti modulu ako súčasti už vyvinutého systému. V poslednom čase sa výraz „unit testing“ častejšie používa v druhom význame, aj keď v tomto prípade hovoríme skôr o integračnom testovaní.



Načítava...
Hore