PDA

View Full Version : سوال: استفاده زیاد از Function ها و Procedure ها در برنامه



بهروز عباسی
چهارشنبه 10 اسفند 1390, 12:26 عصر
درود به همه برنامه نویس های گل:لبخند:

یه سوال در مورد استفاده زیاد از Function ها و Procedure ها در برنامه ها داشتم اونم اینکه اگه داخل یه برنامه به دفعات زیاد این کار انجام بشه باعث کند شدن روند اجرای برنامه میشه یا نه
و در دلفی قابلیتی مثل inline کردن توابع در c++ هست یانه ؟:متفکر:

ممنون میشم دوستان راهنمای کنن.

pezhvakco
چهارشنبه 10 اسفند 1390, 19:20 عصر
استفاده زیاد از Function ها و Procedure ها در برنامه ها داشتم اونم اینکه اگه داخل یه برنامه به دفعات زیاد این کار انجام بشه باعث کند شدن روند اجرای برنامه میشه یا نه
اگه کد نویسی درست باشه و بهینه باشه، هیچ مشکلی نداره .

تابع ها و رویه ها برای کم کردن کدهای تکراری هستند .

بهروز عباسی
چهارشنبه 10 اسفند 1390, 19:43 عصر
تابع ها و رویه ها برای کم کردن کدهای تکراری هستند

حرف شما درسته امامنظور من موقعی که برنامه داره اجرا میشه چون در حین اجرا هرجاکه تابعی فراخوانی شده باشه برنامه باید به اون ادرس مراجعه کنه وبعد از اجرای تابع دوباره به محل قبلی برگرده و برای داشتن ادرس فراخوانی برای مراجعه بعد از اجرای تابع باید عمل ذخیره سازی و بازیابی ادرس ها انجام بشه

حالا اگه این کارها به دفعات زیاد انجام بشه ممکنه باعث کند شدن برنامه های(بزرگ)در سیستم های متوسط(از نظر قدرت پردازش و اجرای برنامه ها)نمیشه؟:متعجب:

یوسف زالی
پنج شنبه 11 اسفند 1390, 00:48 صبح
سلام.
ارجاع به آدرس های حافظه رو مثل ارجاع به هارد در نظر نگیرید. این مساله آنچنان سریع اتفاق می افته که با پنتیوم 2 هم محسوس نیست.
ذخیره و بازیابی آدرس جامپ ها هم معمولا در حافظه رم هست، مگه اینکه خیلی خیلی برنامه بزرگ باشه و حافظه خیلی عظیمی بخواد که نیاز به پیجینگ روی هارد باشه.
اگر قرار باشه برنامه ما 10 درصد تمام رم رو در اشغال بگیره با رم های معمولی یک گیگی یعنی 100000000 آدرس و تمام این اتفاقات همه در رندوم اکسس مموری...
تفاوتش رو که با هارد می دونید؟ رندوم اکسس یعنی دستیابی آنی، معمولا هم با استفاده از دیکدر ها و مولتی پلکسر ها انجام می شه.
در این باره دروس معماری و دیجیتال رو مرور کنید.
فقط حواستون باشه، هر چیز از رم رو بصورت دستی (مثل ساخت اشیا) استفاده می کنید در نهایت به سیستم عامل پس بدید (FREE).
تا می تونید برای سریع شدن برنامه این کار ها رو انجام بدید:
1- از ارجاعات بی مورد به دیتابیس پرهیز کنید
2- حتی المقدور خیلی با هارد کار نداشته باشید
3- اگر مجبور به استفاده از هارد شدید از توصیه های سیستم عامل بهره ببرید، مثل استریم ها و API های مرتبط
4- تا می تونید Order حلقه ها رو کاهش بدید
5- در هنگام استفاده از حلقه اگر مجبور به رفرش هستید این کار رو در هر بار اجرا انجام ندید و مثلا با یک Thread دیگه این کار رو کنید یا هر n بار انجام بدید
6- از استفاده از اشیای سنگین بپرهیزید، مثلا از ProgressBar ها درون حلقه استفاده نکنید
7- در زمانهای ورود اطلاعات در لحظه محاسبات مرتبط رو انجام بدید، نیم ثانیه برای هر محاسبه معطلی هنگام ورود یک دیتا بهتر از صد ثانیه آخر کاره
8- در نهایت اگر بنا به هر دلیلی برنامه کند هست ، یوزر رو معطل نکنید و برنامه رو طوری بنویسید که در چنین مواقعی حس بدی به یوزر دست نده...
امیدوارم کافی باشه.
موفق باشید.

بهروز عباسی
پنج شنبه 11 اسفند 1390, 10:02 صبح
و در دلفی قابلیتی مثل inline کردن توابع در C++‎ هست یانه ؟

اگه ممکنه در ابن باره هم کمک کنید

یوسف زالی
پنج شنبه 11 اسفند 1390, 12:12 عصر
منظور شما رو اگر درست گرفته باشم، در دلفی می تونید با کلمه کلیدی asm کدهای اسمبلی رو مستقیم بنویسید.

بهروز عباسی
پنج شنبه 11 اسفند 1390, 14:27 عصر
ممنون از کمک

این که شما میگین برای اسمبلی inline

چیزی که من میگم اینه:
باC++‎ اگه تابعی رو این لاین تعریف کینم همنگام کامپایل شدن کامپایلر سی هرجاکه اون تابع فراخوانی شده باشه کل کدهای تابع رو کپی میکنه که البته باعث افزایش حجم فایلEXE
میشه و در حقیقت تابع فقط در زمان نوشتن و ویرایش کد ماهیت تابع رو داره و بعداز کامپایل تابعی وجود نداره چون هرجافراخوانی شده یه نسخه ازش اونجا هست و CPU از ابتدا تا انتها کدهارو اجرا میکنه و برای دسترسی به تابع نیاز به پرش به آدرس تابع نداره.

تو دلفی میشه چنین کاری انجام داد؟

یوسف زالی
پنج شنبه 11 اسفند 1390, 21:47 عصر
این اسمش ماکرو هست..
در دلفی فکر نمی کنم وجود داشته باشه یا اگه باشه من نمی دونم.
فرقی در سرعت نمی کنه.
دنبالش نباشید.

Ananas
پنج شنبه 11 اسفند 1390, 23:13 عصر
سلام.
Inline تو دلفی به شکل زیر استفاده میشه:

procedure MyProc(x:Integer); inline;
begi
// ...
end;
function MyFunc(y:Char) : String; inline;
begin
// ..
end;

به سرعت هم فرق میکنه ولی اشکالش اینه که حجم فایل exe رو زیاد میکنه. از این دستور در مواقعی که تابع ها کوچک هستن و به سرعت زیاد احتیاج داری استفاده کن.

یوسف زالی
جمعه 12 اسفند 1390, 02:18 صبح
شما تا به حال تست سرعت گرفتی؟
بر مبنای چه مستنداتی می گی سریع تره؟
چقدر؟
دو میکرو ثانیه در چهار میلیون بار اجرا؟
می صرفه؟

Felony
جمعه 12 اسفند 1390, 05:41 صبح
بعضی موارد که Performance خیلی برای یک برنامه مهم هست و برنامه هم برنامه سنگینی هست , همین چند میلی ثانیه ها وقتی جمع بشن ممکنه زمان پاسخدهی یک برنامه رو چندین ثانیه بالا ببرن ( مثلا برنامه هایی که عدد p ) 3.14 ) رو حساب میکنن یا ...

در کل تعریف توابع به صورت inline زمانی مناسب هست که حجم تابع مورد نظر کم باشه و تعداد دفعات مراجعه بهش خیلی زیاد .

Ananas
جمعه 12 اسفند 1390, 11:33 صبح
شما تا به حال تست سرعت گرفتی؟
بر مبنای چه مستنداتی می گی سریع تره؟
چقدر؟
دو میکرو ثانیه در چهار میلیون بار اجرا؟
می صرفه؟
بله من همیشه دنبال سرعت بیشترم همیشه هم امتحان میکنم چون برنامه هام معمولا حلقه های تکرار طولانی دارند.
برای InLine هم من امتحان کردم البته من تو حلقه که خیلی تابع استفاده میشه امتحان کردم و اونجا هم لازم داشتم ولی شاید تابع بخواد مثلا با زدن یک دکمه یکبار اجرا بشه به قول شما خیلی میلی ثانیش محسوس نیست ولی تو برنامه هایی که یه تابع تو یه حلقه خیلی فراخوانی شه اون موقع قطره قطره جمع گردد ... . اینقدر هم که میگی فرقشون کم نیست. مخصوصا اگه چند تا تابع InLine رو با چند تا تابع معمولی تو برنامه مقایسه کنید اون موقع چند برابر هم میشه فقط یک تابع که نیست شاید ده تا یا بیشتر تابع کوچیک داشته باشی که همدیگرو فراخونی کنن اون موقع خیلی خیلی فرق میکنه. فکر کنم مستندات هم لازم نیست کافیه خودت امتحان کنی.

بهروز عباسی
یک شنبه 14 اسفند 1390, 14:51 عصر
ممنون از همه دوستان بخاطر کمک

اگه میشه بگین چطوری باید تست سرعت بگیرم

Ananas
یک شنبه 14 اسفند 1390, 18:19 عصر
باید از توابعی مثل Now استفاده کنی. خروجی تابع Now از جنس TDateTime هست که معادل هست با double و میتونی با اون به شکل یک عدد اعشاری 64 بیتی کار کنی. یک Now قبل از اجرای مثلا یک تابع یا یک حلقه نسبتا طولانی در حد بالای 3 یا 4 ثانیه (چون اختلاف دقیق تر مشخص بشه) بعد از اجرای تابع هم بلافاصله یک Now دیگه بعد دوتا رو از هم کم کن ببین چقدر شده حالا همیم کارو برای روش دوم (در اینجا Inline) انجام بده حالا دو تا زمان رو با هم مقایسه کن.
مثال :

var
t0, t1 : TDateTime;
I, Count: Integer;
begin
t0 := Now;
Count := 1000;
for i := 0 to Count do
begin
//...
//...
//...
end;
t1 := Now - t0;
ShowMessage('Second of time = ' + FloatToStr(t1 * 24 * 60 * 60));
end;


t1 اختلاف زمان قبل و بعد از اجرای تابع (در اینجا حلقه for) هست ولی اگه بخوایم اون رو بر حسب ثانیه داشته باشیم باید اون رو در 24 * 60 * 60 ضرب کنیم. (شبانه روز 24 ساعت هر ساعت 60 دقیقه هر دقیقه 60 ثانیه.)
همین کار رو برای تابع دوم هم انجام می دیم حالا ثانیه ها رو مقایسه می کنیم.

Felony
یک شنبه 14 اسفند 1390, 20:33 عصر
برای این نوع مقایسه ها از GetTickCount استفاده میکنن , نه توابع DateTime !