Sign in Join
Wiki copytemporary

Avoiding implicit try finally section/id: what changed

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

Title: Avoiding implicit try finally section/id

OldNewLine
1+Adakalanya berguna untuk mengetahui bahwa kompilator dapat melapisi beberapa kode dalam blok implisit try ... finally. Intinya ini diperlukan saat anda menggunakan variabel tipe apapun yang harus diinisialisasi / difinalisasi (misalnya prosedur standar Initialize() dan Finalize() melakukan sesuatu yang berarti dengannya), seperti AnsiString atau Variant atau array dinamis. Atau (hanya dalam FPC sebelum tertanggal 2004-12-26) resource string.
2+
3+Contohnya prosedur seperti
4+
5+ procedure P;
6+ var S: AnsiString;
7+ begin
8+ ... do something with S ...
9+ end;
10+
11+sebenarnya dikompilasi seperti
12+
13+ procedure P;
14+ var S: AnsiString;
15+ begin
16+ Initialize(S);
17+ try
18+ ... do something with S ...
19+ finally Finalize(S) end;
20+ end;
21+
22+Ini diperlukan, untuk memastikan jumlah referensi dari S yang akan dikurangi dengan benar saat prosedur P kan keluar dengan eksepsi. Tapi dalam beberapa kasus ini dapat mempengaruhi secara signifikan kecepatan atas kode yang diberikan.
23+
24+Ini adalah link ke diskusi yang diarsipkan pada daftar fpc-devel berkenaan dengan isu ini, dengan subyek "TList slowness in classes" : <http://www.mail-archive.com/fpc-devel@lists.freepascal.org/msg01367.html>
25+
26+Catatan bahwa ansistring temp vars dapat dibuat secara implisit. Cara yang paling nyata untuk memastikan apa yang terjadi padanya adalah membaca output asm.
27+
28+## Solusi yang Mungkin
29+
30+- BARU! gunakan {\$implicitexceptions off} Pastikan bahwa anda hanya menggunakan ini pada versi rilis dari program anda. Mendebug dapat menjadi masalah dengan sakalr terutama mencari kebocoran memori dan kerusakan.
31+
32+- pisahkan kode yang jarang digunakan yang menyebabkan implisit try finally ke dalam prosedur terpisah. (anda dapat menggunakan prosedure dalam procedure) (diverifikasi)
33+
34+- gunakan parameter const daripada parameter nilai. (hindari untuk mengubah refcount tapi temps masih dapat bermasalah).
35+
36+- gunakan global vars. (harus berhati-hati dengan masalah reentrency di sini dan temps masih dapat bermasalah).
37+
38+- gunakan non tipe refcounted seperti shortstrings.
39+
40+## Program Demo
41+
42+Dan di bawah ini adalah program demo kecil yang
43+
44+- Ketika dijalankan, dengan jelas memperlihatkan bahwa menghindari implisit blok try ... finally dapat menjadikan kode jauh lebih cepat. Ketika saya menjalan program ini pada sistem saya, Saya memperoleh
45+
46+`Time of Foo_Normal: 141`\
47+`Time of Foo_Faster: 17`
48+
49+- Memperlihatkan trik bagaimana untuk menghindari implisit blok try ... finally (tanpa mengubah arti atau keamanan kode) dalam beberapa kasus (ketika anda tidak memerlukannya gunakan AnsiString/Variant/something setiap kali procedure dipanggil tapi misalnya hanya jika beberapa parameter memiliki nilai tertentu).
50+
51+ {$mode objfpc}{$H+}
52+
53+ uses
54+ {BaseUnix, Unix hanya diperlukan untuk mengimplementasi Clock} BaseUnix, Unix,
55+ SysUtils;
56+
57+ function Clock: Int64;
58+ var Dummy: tms;
59+ begin
60+ Clock := FpTimes(Dummy);
61+ end;
62+
63+ procedure Foo_Normal(i: Integer);
64+ var S: string;
65+ begin
66+ if i = -1 then
67+ begin
68+ S := 'Some operation with AnsiString';
69+ raise Exception.Create(S);
70+ end;
71+ end;
72+
73+ procedure Foo_Faster(i: Integer);
74+
75+ procedure RaiseError;
76+ var S: string;
77+ begin
78+ S := 'Some operation with AnsiString';
79+ raise Exception.Create(S);
80+ end;
81+
82+ begin
83+ if i = -1 then RaiseError;
84+ end;
85+
86+ { Catatan bahwa ketika saya memanggil Foo_Normal dan Foo_ResourceString
87+ i selalu >= 0 maka Eksepsi tidak pernah dimunculkan.
88+ Maka konstan string SNormal dan SResString tidak benar-benar dipakai. }
89+
90+ const
91+ TestCount = 10000000;
92+ var
93+ i: Integer;
94+ Start: Int64;
95+ begin
96+ Start := Clock;
97+ for i := 0 to TestCount do Foo_Normal(i);
98+ Writeln('Time of Foo_Normal: ', Clock - Start);
99+
100+ Start := Clock;
101+ for i := 0 to TestCount do Foo_Faster(i);
102+ Writeln('Time of Foo_Faster: ', Clock - Start);
103+ end.
104+
105+---
106+*From the Free Pascal wiki, page "Avoiding implicit try finally section/id", as it stood on 2015-07-22 after a change by FTurtle, 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).*

Back to history