Avoiding implicit try finally section/fi: what changed
Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.
| Old | New | Line | |
|---|---|---|---|
| 1 | + | ## Contents | |
| 2 | + | ||
| 3 | + | * 1 Epäsuoran try finally lohkon välttäminen | |
| 4 | + | * 1.1 Yleistä | |
| 5 | + | * 1.2 Mahdolliset ratkaisut | |
| 6 | + | * 1.3 riskejä ja milloin niitä sovelletaan | |
| 7 | + | * 1.4 Demo-ohjelma | |
| 8 | + | ||
| 1 | 9 | # Epäsuoran try finally lohkon välttäminen | |
| 2 | 10 | ||
| 3 | 11 | ## Yleistä | |
| 4 | 12 | ||
| 5 | - | ||
| 13 | + | Koodin optimoinnissa se auttaa ymmärtämään, että [[Compiler/fi|kääntäjä]] käärii tiettyjä koodirakenteita epäsuorasti [[Try/fi|`try`]] … [[Finally/fi|`finally`]]-[lohkoon](</index.php?title=Block/fi&action=edit&redlink=1> "Block/fi \(page does not exist\)"). Tämä on tarpeen aina, kun käytetään sellaisia [[Variable/fi|muuttujia]], kuten [[Ansistring|`ansiString`]], [[Variant|`variant`s]] tai [[Dynamic array/fi|dynaamisia taulukoita]] jotka edellyttävät [[Initialization|initialization]] ja [[Finalization|finalization]] (esim. kun standardi [[Procedure/fi|aliohjelmat]] `initialize` ja `finalize` tarvitaan oikean muistin allokoinnin ja hankitun muistin vapauttamiseksi). | |
| 6 | 14 | ||
| 7 | - | ||
| 15 | + | Tällöin kääntäjä varmistaa, että msg: n viitenumero lasketaan asianmukaisesti, kun menettely doSomething poistuu poikkeuksella. Usein tämä voi kuitenkin aiheuttaa merkittäviä haitallisia vaikutuksia tuotetun koodin nopeuteen. | |
| 8 | 16 | ||
| 9 | - | ||
| 17 | + | Tämä oli ongelma, joka oli `fpc-devel` -sähköpostilistan aiheketjussa <http://www.mail-archive.com/fpc-devel@lists.freepascal.org/msg01367.html> `TList` slowness classes . | |
| 10 | 18 | ||
| 11 | - | ||
| 19 | + | Huomaa, että väliaikaiset `ansiString`-muuttujat voidaan luoda epäsuorasti. Ainoa tapa olla täysin varma siitä, mitä todellisuudessa tehdään, on lukea [assemblerin](</index.php?title=Assembler/fi&action=edit&redlink=1> "Assembler/fi \(page does not exist\)") ulostulo. | |
| 12 | 20 | ||
| 13 | 21 | ## Mahdolliset ratkaisut | |
| 14 | 22 | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 23 | + | * Käytetään [`{$implicitexceptions off}`](</index.php?title=sImplicitExeptions&action=edit&redlink=1> "sImplicitExeptions \(page does not exist\)"): Varmistetaan, että tämä koskee vain julkaistuja versioita. Virheenjäljitys voi muuttua hankalaksi, kun siirrytään erityisesti muistivuotoihin ja korruptioon. | |
| 24 | + | * Irrotetaan harvoin käytetty koodi, joka aiheuttaa implisiittisen `try…finally` eri aliohjelmiin. (Voidaan käyttää aliohjelmissa aliohjelmia) | |
| 25 | + | * Käytetään [[Const|`const` parametreja]] arvoparametrien sijaan. Näin vältetään tarve muuttaa viittausosoitusta, mutta tilapäiset muuttujat voivat edelleen olla ongelma. | |
| 26 | + | * Käytetään [[Global variables|globaaleja muuttujia]]: Sinun on kuitenkin oltava varovainen uusintakysymyksissä, mutta väliaikaiset muuttujat voivat silti olla ongelma. | |
| 27 | + | * Käytetään ei-viitteellisiä tyyppejä, kuten [[Shortstring|`shortstring`]]. | |
| 20 | 28 | ||
| 21 | 29 | ## riskejä ja milloin niitä sovelletaan | |
| 22 | 30 | ||
| 23 | - | ||
| 31 | + | [](</File:Warning-icon.png>) | |
| 24 | 32 | ||
| 25 | - | ||
| 33 | + | **Warning:** Nämä poikkeuskehykset luodaan syystä. Jos niistä jätetään poikkeus niin koodiin jään muistivuoto mahdollisuus | |
| 26 | 34 | ||
| 27 | - | ||
| 28 | - | ||
| 29 | - | ||
| 30 | - | ||
| 35 | + | ||
| 36 | + | Vuonna 2007 [`{$implicitExceptions}`](</index.php?title=sImplicitExceptions&action=edit&redlink=1> "sImplicitExceptions \(page does not exist\)") lisättiin [`strutils`](<https://www.freepascal.org/docs-html/rtl/strutils/index.html>)-[[Unit/fi|käännösyksikköön]]. Jota [sysutils](<https://www.freepascal.org/docs-html/rtl/sysutils/index.html>) on luultavasti seurannut. Tätä varten noudatettiin seuraavaa lähestymistapaa: | |
| 31 | 37 | ||
| 32 | - | ||
| 38 | + | * [[Routine/fi|Rutiini]], joka kutsuu rutiinia, joka [[Raise/fi|nostaa]] poikkeuksia, on vaarallinen - esim. [`strToInt`](<https://www.freepascal.org/docs-html/rtl/sysutils/strtoint.html>), mutta ei [`strToIntDef`](<https://www.freepascal.org/docs-html/rtl/sysutils/strtointdef.html>). | |
| 39 | + | * Poikkeuksia aiheuttavat rutiinit on huomioitavia. | |
| 40 | + | * Hyvin suuret rutiinit eivät ole vaivan arvoista, koska riski ja alhaiset edut - esim. [päivämäärän muotoilurutiinit](<https://www.freepascal.org/docs-html/rtl/sysutils/datetimeroutines.html>). | |
| 41 | + | * Desimaalilukujen käyttö voi nostaa poikkeuksia, jotka muunnetaan [[sysutils|`sysUtils`]]-ohjelmien avulla. En ole varma, onko tämä todellakin riittävä syy, mutta ohitin Desimaalilukujen käytön käyttämällä näitä rutiineja aluksi tästä syystä. | |
| 33 | 42 | ||
| 43 | + | Jos havaitset näitä muutoksia, ota yhteyttä [Marcoviin](</User:Marcov> "User:Marcov"). | |
| 44 | + | ||
| 34 | 45 | ## Demo-ohjelma | |
| 35 | 46 | ||
| 36 | 47 | Alla on pieni demo-[[Program/fi|ohjelma]] | |
| 37 | 48 | ||
| 38 | - | ||
| 39 | - | ||
| 40 | - | ||
| 41 | - | ||
| 42 | - | ||
| 43 | - | ||
| 44 | - | ||
| 45 | - | ||
| 46 | - | ||
| 47 | - | ||
| 48 | - | ||
| 49 | - | ||
| 50 | - | ||
| 51 | - | ||
| 52 | - | ||
| 53 | - | ||
| 54 | - | ||
| 55 | - | ||
| 56 | - | ||
| 57 | - | ||
| 58 | - | ||
| 59 | - | ||
| 60 | - | ||
| 61 | - | ||
| 62 | - | ||
| 63 | - | ||
| 64 | - | ||
| 65 | - | ||
| 66 | - | ||
| 67 | - | ||
| 68 | - | ||
| 69 | - | ||
| 70 | - | ||
| 71 | - | ||
| 72 | - | ||
| 73 | - | ||
| 74 | - | ||
| 75 | - | ||
| 76 | - | ||
| 77 | - | ||
| 49 | + | Sen suorittaessaan osoittaa selvästi, että epäsuoran `try … finally` välttäminen mhdollistaa koodin suorittamisen paljon nopeammin. Kun suoritin tämän ohjelman järjestelmässäni, sain tuloksen: | |
| 50 | + | ``` | |
| 51 | + | time of fooNormal: 141 | |
| 52 | + | time of fooFaster: 17 | |
| 53 | + | ``` | |
| 78 | 54 | ||
| 79 | - | ||
| 80 | - | ||
| 81 | - | ||
| 55 | + | * Tässä näytetään temppu, jolla vältetään epäsuoria `try … finally` \- lohkoja (muuttamatta koodin merkitystä tai turvallisuutta) joissakin tapauksissa (kun sinun ei tarvitse tosiasiallisesti käyttää tätä [[Ansistring|`AnsiString`]]/ | |
| 82 | 56 | ||
| 83 | - | ||
| 84 | - | ||
| 85 | - | ||
| 86 | - | ||
| 87 | - | ||
| 88 | - | ||
| 89 | - | ||
| 90 | - | ||
| 91 | - | ||
| 92 | - | ||
| 57 | + | [[Variant|`Variant`-tyyppiä]]/ jotakin muuta tyyppiä joka kerta kun aliohjelmaa kutsutaan mutta vain jos jollakin parametrilla on tietty arvo). | |
| 93 | 58 | ||
| 94 | - | ||
| 95 | - | ||
| 96 | - | ||
| 97 | - | ||
| 98 | - | ||
| 99 | - | ||
| 100 | - | ||
| 101 | - | ||
| 102 | - | ||
| 103 | - | ||
| 104 | - | ||
| 105 | - | ||
| 106 | - | ||
| 107 | - | ||
| 59 | + | ||
| 108 | 60 | ||
| 109 | - | ||
| 110 | - | ||
| 111 | - | ||
| 112 | - | ||
| 113 | - | ||
| 114 | - | ||
| 115 | - | ||
| 116 | - | ||
| 117 | - | ||
| 118 | - | ||
| 119 | - | ||
| 120 | - | ||
| 121 | - | ||
| 122 | - | ||
| 123 | - | ||
| 124 | - | ||
| 125 | - | ||
| 126 | - | ||
| 127 | - | ||
| 128 | - | ||
| 129 | - | ||
| 130 | 61 | ``` | |
| 62 | + | 1program implicitExceptionDemo(input, output, stderr); | |
| 63 | + | 2 | |
| 64 | + | 3// for exceptions | |
| 65 | + | 4{$mode objfpc} | |
| 66 | + | 5// data type 'string' refers to 'ansistring' | |
| 67 | + | 6{$longstrings on} | |
| 68 | + | 7 | |
| 69 | + | 8uses | |
| 70 | + | 9 {$IFDEF UNIX} | |
| 71 | + | 10 // baseUnix, unix needed only to implement clock | |
| 72 | + | 11 BaseUnix, Unix, | |
| 73 | + | 12 {$ENDIF} | |
| 74 | + | 13 sysUtils; | |
| 75 | + | 14 | |
| 76 | + | 15function clock(): int64; | |
| 77 | + | 16 | |
| 78 | + | 17var | |
| 79 | + | 18 {$IFDEF UNIX} | |
| 80 | + | 19 dummy: tms; | |
| 81 | + | 20 {$ELSE} | |
| 82 | + | 21 TS : TTimeStamp; | |
| 83 | + | 22 {$ENDIF} | |
| 84 | + | 23begin | |
| 85 | + | 24 {$IFDEF UNIX} | |
| 86 | + | 25 clock := fpTimes(dummy); | |
| 87 | + | 26 {$ELSE} | |
| 88 | + | 27 TS:=DateTimeToTimeStamp(Now); | |
| 89 | + | 28 result := TS.Time; | |
| 90 | + | 29 {$ENDIF} | |
| 91 | + | 30end; | |
| 92 | + | 31 | |
| 93 | + | 32 | |
| 94 | + | 33 | |
| 95 | + | 34// Note: when fooNormal and fooFaster are called | |
| 96 | + | 35// i is always >= 0, so no exception is ever actually raised. | |
| 97 | + | 36// So string constants SNormal and SResString are not really used. | |
| 98 | + | 37 | |
| 99 | + | 38procedure fooNormal(i: integer); | |
| 100 | + | 39var | |
| 101 | + | 40 s: string; | |
| 102 | + | 41begin | |
| 103 | + | 42 if i = -1 then | |
| 104 | + | 43 begin | |
| 105 | + | 44 s := 'Some operation with AnsiString'; | |
| 106 | + | 45 raise exception.create(s); | |
| 107 | + | 46 end; | |
| 108 | + | 47end; | |
| 109 | + | 48 | |
| 110 | + | 49procedure fooFaster(i: integer); | |
| 111 | + | 50 procedure raiseError; | |
| 112 | + | 51 var | |
| 113 | + | 52 s: string; | |
| 114 | + | 53 begin | |
| 115 | + | 54 s := 'Some operation with AnsiString'; | |
| 116 | + | 55 raise exception.create(s); | |
| 117 | + | 56 end; | |
| 118 | + | 57begin | |
| 119 | + | 58 if i = -1 then | |
| 120 | + | 59 begin | |
| 121 | + | 60 raiseError; | |
| 122 | + | 61 end; | |
| 123 | + | 62end; | |
| 124 | + | 63 | |
| 125 | + | 64 | |
| 126 | + | 65// M A I N ================================================= | |
| 127 | + | 66const | |
| 128 | + | 67 testCount = 10000000; | |
| 129 | + | 68var | |
| 130 | + | 69 i: integer; | |
| 131 | + | 70 start: int64; | |
| 132 | + | 71begin | |
| 133 | + | 72 start := clock(); | |
| 134 | + | 73 for i := 0 to testCount do | |
| 135 | + | 74 begin | |
| 136 | + | 75 fooNormal(i); | |
| 137 | + | 76 end; | |
| 138 | + | 77 writeLn('time of fooNormal: ', clock() - start); | |
| 139 | + | 78 | |
| 140 | + | 79 start := clock(); | |
| 141 | + | 80 for i := 0 to testCount do | |
| 142 | + | 81 begin | |
| 143 | + | 82 fooFaster(i); | |
| 144 | + | 83 end; | |
| 145 | + | 84 writeLn('time of fooFaster: ', clock() - start); | |
| 146 | + | 85end. | |
| 147 | + | ``` | |
| 131 | 148 | ||
| 132 | 149 | Laittamalla `raiseError` toiseen [[Scope|näkyvyyteen]] `fooFaster` aliohjelmassa, keskeysten käsittely ei tule osaksi pääkäyttöistä suoritusosaa. | |
| 133 | 150 | ||
| 134 | 151 | --- | |
| 135 | - | ||
| 152 | + | *From the Free Pascal wiki, page "Avoiding implicit try finally section/fi", as the Internet Archive kept it on 2022-08-13. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* |
