Sign in Join
Wiki copytemporary

Avoiding implicit try finally section/fi: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
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+
19# Epäsuoran try finally lohkon välttäminen
210
311## Yleistä
412
5-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]]-[[Block/fi|lohkoon]]. Tämä on tarpeen aina, kun käytetään sellaisia [[Variable/fi|muuttujia]], kuten [[Ansistring|ansiString]], [[Variant|variants]] 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).
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).
614
7-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.
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.
816
9-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 .
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 .
1018
11-Huomaa, että väliaikaiset `ansiString`-muuttujat voidaan luoda epäsuorasti. Ainoa tapa olla täysin varma siitä, mitä todellisuudessa tehdään, on lukea [[Assembler/fi|assemblerin]] ulostulo.
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.
1220
1321## Mahdolliset ratkaisut
1422
15-- Käytetään [[sImplicitExeptions|{$implicitexceptions off}]]: Varmistetaan, että tämä koskee vain julkaistuja versioita. Virheenjäljitys voi muuttua hankalaksi, kun siirrytään erityisesti muistivuotoihin ja korruptioon.
16-- Irrotetaan harvoin käytetty koodi, joka aiheuttaa implisiittisen `try…finally` eri aliohjelmiin. (Voidaan käyttää aliohjelmissa aliohjelmia)
17-- Käytetään [[Const|const parametreja]] arvoparametrien sijaan. Näin vältetään tarve muuttaa viittausosoitusta, mutta tilapäiset muuttujat voivat edelleen olla ongelma.
18-- Käytetään [[Global variables|globaaleja muuttujia]]: Sinun on kuitenkin oltava varovainen uusintakysymyksissä, mutta väliaikaiset muuttujat voivat silti olla ongelma.
19-- Käytetään ei-viitteellisiä tyyppejä, kuten [[Shortstring|shortstring]].
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`]].
2028
2129## riskejä ja milloin niitä sovelletaan
2230
23-> **Warning:** Nämä poikkeuskehykset luodaan syystä. Jos niistä jätetään poikkeus niin koodiin jään muistivuoto mahdollisuus
31+[![Warning-icon.png](/wiki-images/b/b2/Warning-icon.png)](</File:Warning-icon.png>)
2432
25-Vuonna 2007 [[sImplicitExceptions|{$implicitExceptions}]] 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:
33+**Warning:** Nämä poikkeuskehykset luodaan syystä. Jos niistä jätetään poikkeus niin koodiin jään muistivuoto mahdollisuus
2634
27-- [[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).
28-- Poikkeuksia aiheuttavat rutiinit on huomioitavia.
29-- 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).
30-- 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ä.
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:
3137
32-Jos havaitset näitä muutoksia, ota yhteyttä Marcoviin.
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ä.
3342
43+Jos havaitset näitä muutoksia, ota yhteyttä [Marcoviin](</User:Marcov> "User:Marcov").
44+
3445## Demo-ohjelma
3546
3647Alla on pieni demo-[[Program/fi|ohjelma]]
3748
38-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:
39-
40-`time of fooNormal: 141`\
41-`time of fooFaster: 17`
42-
43-- 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]]/
44-
45-[[Variant|Variant-tyyppiä]]/ jotakin muuta tyyppiä joka kerta kun aliohjelmaa kutsutaan mutta vain jos jollakin parametrilla on tietty arvo).
46-
47-``` pascal
48-program implicitExceptionDemo(input, output, stderr);
49-
50-// for exceptions
51-{$mode objfpc}
52-// data type 'string' refers to 'ansistring'
53-{$longstrings on}
54-
55-uses
56- {$IFDEF UNIX}
57- // baseUnix, unix needed only to implement clock
58- BaseUnix, Unix,
59- {$ENDIF}
60- sysUtils;
61-
62-function clock(): int64;
63-
64-var
65- {$IFDEF UNIX}
66- dummy: tms;
67- {$ELSE}
68- TS : TTimeStamp;
69- {$ENDIF}
70-begin
71- {$IFDEF UNIX}
72- clock := fpTimes(dummy);
73- {$ELSE}
74- TS:=DateTimeToTimeStamp(Now);
75- result := TS.Time;
76- {$ENDIF}
77-end;
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+```
7854
79-// Note: when fooNormal and fooFaster are called
80-// i is always >= 0, so no exception is ever actually raised.
81-// So string constants SNormal and SResString are not really used.
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`]]/
8256
83-procedure fooNormal(i: integer);
84-var
85- s: string;
86-begin
87- if i = -1 then
88- begin
89- s := 'Some operation with AnsiString';
90- raise exception.create(s);
91- end;
92-end;
57+[[Variant|`Variant`-tyyppiä]]/ jotakin muuta tyyppiä joka kerta kun aliohjelmaa kutsutaan mutta vain jos jollakin parametrilla on tietty arvo).
9358
94-procedure fooFaster(i: integer);
95- procedure raiseError;
96- var
97- s: string;
98- begin
99- s := 'Some operation with AnsiString';
100- raise exception.create(s);
101- end;
102-begin
103- if i = -1 then
104- begin
105- raiseError;
106- end;
107-end;
59+
10860
109-// M A I N =================================================
110-const
111- testCount = 10000000;
112-var
113- i: integer;
114- start: int64;
115-begin
116- start := clock();
117- for i := 0 to testCount do
118- begin
119- fooNormal(i);
120- end;
121- writeLn('time of fooNormal: ', clock() - start);
122-
123- start := clock();
124- for i := 0 to testCount do
125- begin
126- fooFaster(i);
127- end;
128- writeLn('time of fooFaster: ', clock() - start);
129-end.
13061```
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+```
131148
132149Laittamalla `raiseError` toiseen [[Scope|näkyvyyteen]] `fooFaster` aliohjelmassa, keskeysten käsittely ei tule osaksi pääkäyttöistä suoritusosaa.
133150
134151---
135-*From the Free Pascal wiki, page "Avoiding implicit try finally section/fi", as it stood on 2022-08-06 after a change by Kai Burghardt, out of the wiki's dump of 2024-05-26. 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).*
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).*

Back to history