View Full Version : حرفه ای: بهترین مکان برای تعریف یه متغییر حلقه
MohsenB
یک شنبه 01 آبان 1390, 20:59 عصر
سلام
بهترین مکان برای تعریف یه متغییر که درون یه حلقه از یه تابع که اون تابع دفعات زیادی صدا زده میشه درون هموم تابع هستش یا تعریفش بصورت عمومی بهتره ؟
یا به زبان دیگر ساخت مداوم یک متغییر سریعتر و معقولتره یا دستیابی به یه متغییر عمومی ؟
برا مثال یه حالت ساده رو براتون مینویسم :
این حالت اوله :
var i :integer;
procedure test1;
begin
for i:= 0 to 2000 do
some code
end;
procedure test2;
begin
while(true) do
test1;
end;
این نوع دوم :
procedure test1;
var i :integer;
begin
for i:= 0 to 2000 do
some code
end;
procedure test2;
begin
while(true) do
test1;
end;
توضیح اینکه این یه کد نمونه هست و کد اصلی طور دیگریست . و منظورم از حلقه در test2 اینه که تابع test1 مداوم صدا زده میشه .
باتشکر
tdkhakpur
یک شنبه 01 آبان 1390, 22:55 عصر
یا به زبان دیگر ساخت مداوم یک متغییر سریعتر و معقولتره یا دستیابی به یه متغییر عمومی ؟
خب وقتی عمومی تعریف کنید فقط زمانی که برنامه لود میشه حافظه براش رزرو میشه اما داخل توابع باید از پشته کمک گرفته بشه پس نتیجه این میشه عمومی سریعتره اما بهتر بودنش بستگی به نوع نرم افزار داره.
SAASTN
یک شنبه 01 آبان 1390, 23:42 عصر
خوب با یکم تغییر کدی که قرار دادین میشه این مسئله رو آزمایش کرد:
function Test1(InnerCount: Integer): Integer;
begin
Result := 0;
for I := 0 to InnerCount - 1 do
Inc(Result);
end;
function Test2(InnerCount: Integer): Integer;
var
J: Integer;
begin
Result := 0;
for J := 0 to InnerCount - 1 do
Inc(Result);
end;
procedure TForm1.Button1Click(Sender: TObject);
const
InnerCount = 2000;
OuterCount = 100000;
var
I, Test1TickCount, Test2TickCount: Integer;
begin
Test1TickCount := GetTickCount;
for I := 0 to OuterCount - 1 do
Test1(InnerCount);
Test1TickCount := GetTickCount - Test1TickCount;
Test2TickCount := GetTickCount;
for I := 0 to OuterCount - 1 do
Test2(InnerCount);
Test2TickCount := GetTickCount - Test2TickCount;
Caption := Format('Global:%d Local: %d', [Test1TickCount, Test2TickCount])
end;
جوابی که من رو سیستمم با همون مقادیر بالا گرفتم 499 میلی ثانیه برای متغیر سراسری در مقابل 733 میلی ثانیه برای متغیر محلی بود. آزمایش این مسئله تو کد نهایی هم به همین تریب ساده س.
اما توجه داشته باشید که استفاده از متغیر سراسری برای for این اخطار کامپایلر رو به دنبال داره:
[DCC Warning] Unit1.pas(31): W1019 For loop control variable must be simple local variable
تو راهنما هم میگه این کار فقط برای حفظ سازگاری کدهای ورژن های پائین تر مجازه و باعث تولید کد پیچیپده تری توسط کامپایلر میشه.
MohsenB
یک شنبه 01 آبان 1390, 23:50 عصر
خب وقتی عمومی تعریف کنید فقط زمانی که برنامه لود میشه حافظه براش رزرو میشه اما داخل توابع باید از پشته کمک گرفته بشه پس نتیجه این میشه عمومی سریعتره اما بهتر بودنش بستگی به نوع نرم افزار داره.
سلام
ممنون از پاسختون
بیشتر بحث من روی سرعت هست . و برنامه من یه برنامه پردازش تصویره و توش سرعت پردازش مجموعه ای از اطلاعات خیلی باید سریع باشه .
نمیدونم ، شاید صحبت شما درست باشه ولی آیا از نظر سرعت دستیابیی که نرم افزار به متغییر محلی میزنه با عمومی یکسانه ؟
فکر کنم یه بحث هایی در سطح سیستم عامل هست که میگه وقتی یه تابع صدا زده میشه که اون تابع توش یه متغییر ساخته میشه اون متغییر توی صفحه ای از حافظه قرار داده میشه که نزدیکتر به دستورات اون تابع هست ، پس وقتی اون صفحه به کش سی پی یو میره دستیابی بهش سریعتر انجام میشه . و اینجوری سرعت دسترسی به اون متغییر محلی از سرعت دسترسی به لود کردن صفحه ای دیگر و دستیابی به متغییر عمومی بیشتره .
شاید بگین این بستگی به معماری سی پی یو و یا سیستم عامل و یا کامپایلر داره ، برا همین شما سی پی یو رو Intel Cori5 و سیستم عامل رو ویندوز 7 64Bit و کامپایلر رو کامپایلر دلفی 64Bit XE2 در نظر بگیرید .
حالا نمیدونم درست گفتم یا نه . لطفا اساتید راهنمایی کنن .
loo30fer
یک شنبه 01 آبان 1390, 23:56 عصر
خب وقتی عمومی تعریف کنید فقط زمانی که برنامه لود میشه حافظه براش رزرو میشه اما داخل توابع باید از پشته کمک گرفته بشه پس نتیجه این میشه عمومی سریعتره اما بهتر بودنش بستگی به نوع نرم افزار داره.
سلام
اما دوست من بنده خیال میکنم فرقی نمیکنه چون متغیر عمومی هنگام لود برنامه تعریف میشه و تا هنگام بسته شدن برنامه توی رم میمونه ولی وقتی بعضی متغیرها که خودشون تخصیص حافظه داده میشن مانند همین Integer توی یک تابع تعریف بشه همون لحظه اون متغیر ایجاد میشه و تا آخر کار تابع هم توی رم میمونه و بعد از اتمام هم تخصیص حافظه داده میشه پس در هر دو شکل توی حلقه تعداد باری که حلقه دور میزنه اون مقدار توی تون متغیر ریخته میشه پس نباید فرقی در سرعت کار این دو وجود داشته باشد. ضمنا در مورد پشتک خوندم ولی به خاطر توضیحات پیچیده و نامفهموم نتونستم درست متوجه نحوه کار بشم اگه امکان داره توضیحاتی در اینباره بدین چون برام سوال شده اگه بدین شکل هست پس چرا وقتی که حلقه ای رو مینویسم و Enter رو میزنیم خودش متغیر رو داخل اون تابع یا دکمه تعریف میکنه در صورتی که طبق گفته شما سرعت عملکرد پایین تری نسبت به متغیر عمومی داره درست مانند کار Application.ProcessMessages که نسبت به Thread از سرعت پایین تری برخورداره.
MohsenB
یک شنبه 01 آبان 1390, 23:58 عصر
خوب با یکم تغییر کدی که قرار دادین میشه این مسئله رو آزمایش کرد:
...
جوابی که من رو سیستمم با همون مقادیر بالا گرفتم 499 میلی ثانیه برای متغیر سراسری در مقابل 733 میلی ثانیه برای متغیر محلی بود. آزمایش این مسئله تو کد نهایی هم به همین تریب ساده س.
اما توجه داشته باشید که استفاده از متغیر سراسری برای for این اخطار کامپایلر رو به دنبال داره:
[DCC Warning] Unit1.pas(31): W1019 For loop control variable must be simple local variable
تو راهنما هم میگه این کار فقط برای حفظ سازگاری کدهای ورژن های پائین تر مجازه و باعث تولید کد پیچیپده تری توسط کامپایلر میشه.
سلام
ممنون از راهنماییتون
ولی همون طور که توضیح دادم از نظر تئوری خلاف این ارقام باید بدست بیاد . البته شایدم بخاطر حجم کم برنامه مورد آزمایش باشه که کلش میتونه تو یه صفحه باشه و یا اصلا تئوریی که مطرح کردم درست نباشه .
من کدتون رو امتحان کردم برای من این نتایج رو داشت :
32 بیت ، حالت دیباگ : اولی 437 دومی 493
32 بیت ، حالت اجرا : اولی 437 دومی 437
64 بیت ، حالت اجرا : اولی 515 دومی 515
؟؟؟؟
MohsenB
دوشنبه 02 آبان 1390, 00:06 صبح
اگه بدین شکل هست پس چرا وقتی که حلقه ای رو مینویسم و Enter رو میزنیم خودش متغیر رو داخل اون تابع یا دکمه تعریف میکنه
شما فکر کنم یه نرم افزار جانبی مثل Castalia نصب کردین وگرنه خودش بصورت پیش فرض همچین کاری نمیکنه
در صورتی که طبق گفته شما سرعت عملکرد پایین تری نسبت به متغیر عمومی داره درست مانند کار Application.ProcessMessages که نسبت به Thread از سرعت پایین تری برخورداره.
این دو هیچ ربطی بهم ندارند
loo30fer
دوشنبه 02 آبان 1390, 00:27 صبح
شما فکر کنم یه نرم افزار جانبی مثل Castalia نصب کردین وگرنه خودش بصورت پیش فرض همچین کاری نمیکنهخیر شما وقتی توی تابع یا دکمه ای for رو مینویسین به صورت پیشفرض I:=0 رو اضافه میکنه و وقتی همون زمان دکمه Enter رو فشار بدین همون متغیر رو براتون تعریف میکنه که فکر میکنم این قابلیت برای دلفی 2009 و به بعد پیاده شده.
این دو هیچ ربطی بهم ندارند منم نگفتم این دو به هم ربط دارن ولی یکجورایی بی ربط هم نیستن چون هر دو برای جلوگیری از فریز شدن برنامه به کار میرن که البته همونطور که خودتونم میدونید Application.ProcessMessages بیشتر برای مواقعی مناسبه که یک مقدار یا عملیاتی به صورت متداول فراخوانی یا اجرا میشه مثلا حلقه یا عملیات کپی که اگه مقدار خواندن از فایل بیش از حد باشه کاری از Application.ProcessMessages ساخته نیست حتی اگه زیادی هم این مقدار خواندن فایل بزرگ باشه اگه توی Thread تعریف هم شده باشه وقتی موس رو روی اون فرم حرکت بدین میبینید که موس یکم با کندی حرکت میکنه و فرم رو نمیتونید سریع تکون بدین.
بهرحال این تاپیک شما باعث شد چیز جدید و نکته ظریفی رو یاد بگیرم که ازتون ممنونم.
MohsenB
دوشنبه 02 آبان 1390, 02:30 صبح
خیر شما وقتی توی تابع یا دکمه ای for رو مینویسین به صورت پیشفرض I:=0 رو اضافه میکنه و وقتی همون زمان دکمه Enter رو فشار بدین همون متغیر رو براتون تعریف میکنه که فکر میکنم این قابلیت برای دلفی 2009 و به بعد پیاده شده.
منم نگفتم این دو به هم ربط دارن ولی یکجورایی بی ربط هم نیستن چون هر دو برای جلوگیری از فریز شدن برنامه به کار میرن که البته همونطور که خودتونم میدونید Application.ProcessMessages بیشتر برای مواقعی مناسبه که یک مقدار یا عملیاتی به صورت متداول فراخوانی یا اجرا میشه مثلا حلقه یا عملیات کپی که اگه مقدار خواندن از فایل بیش از حد باشه کاری از Application.ProcessMessages ساخته نیست حتی اگه زیادی هم این مقدار خواندن فایل بزرگ باشه اگه توی Thread تعریف هم شده باشه وقتی موس رو روی اون فرم حرکت بدین میبینید که موس یکم با کندی حرکت میکنه و فرم رو نمیتونید سریع تکون بدین.
بهرحال این تاپیک شما باعث شد چیز جدید و نکته ظریفی رو یاد بگیرم که ازتون ممنونم.
سلام
این حالتی که میفرمایید تو هیچکدوم از نسخه های دلفی نیست و با نصب نرم افزارایی مثل Castalia و یا CnWizard و یا ... بهش اضافه میشه .
دستور Application.ProcessMessages به برنامه میگه که پیامهایی که بهش صادر شده رو اجرا کن .
در مورد Thread هم باید بگم که برنامه هایی که درون سیستم عامل ویندوز اجرا میشن بصورت پیشفرض هر برنامه درون یک سرنخ ( Thread یا دنباله ای از دستورات برنامه ) قرار می گیرند که ویندوز یکی یکی از هر سرنخ همه برنامه ها به یه مقدار مشخص دستورات رو اجرا میکنه . بخاطر همینه که ما تمام برنامه های درون ویندوز رو احساس میکنیم باهم دارن اجرا میشن . حالا اگه تو سرنخ یه برنامه یه کار پر مشغله مثل چیزی که شما مثال زدین اتفاق بیفته شما میتونید با دستور Application.ProcessMessages پیامهایی رو که به برنامه فرستاده شده رو یک بار پردازش کنید و بعد به دنبال بقیه سرنخ برین . هر برنامه هم میتونه چند سرنخ داشته باشه (منظور شما از سرنخ این مقوله است ) که میتونه بطور مجزا پردازش بشه و بخاطر همین توقف و یا اختلال در یکی روی دیگری تاثیری ندارد . این بحث خیلی مفصل میباشد و ادامه این بحث مربوط به این تاپیک نیست . فقط جهت اطلاع عرض کردم .
Felony
دوشنبه 02 آبان 1390, 20:01 عصر
بهترین مکان برای تعریف یه متغییر که درون یه حلقه از یه تابع که اون تابع دفعات زیادی صدا زده میشه درون هموم تابع هستش یا تعریفش بصورت عمومی بهتره ؟
تعریف متغییر به صورت عمومی در برنامه نویسی شئ گرائی به هیچ عنوان معنایی نداره مگر در شرایط خیلی خیلی خاص !
اگه بدین شکل هست پس چرا وقتی که حلقه ای رو مینویسم و Enter رو میزنیم خودش متغیر رو داخل اون تابع یا دکمه تعریف میکنه در صورتی که طبق گفته شما سرعت عملکرد پایین تری نسبت به متغیر عمومی داره
به همون دلیل بالا که گفتم .
این حالتی که میفرمایید تو هیچکدوم از نسخه های دلفی نیست و با نصب نرم افزارایی مثل Castalia و یا CnWizard و یا ... بهش اضافه میشه .
عجب ، پس دلفی ما چندین ساله تو توهم به سر میبره !
@ MohsenB : الگوریتمت رو درست انتخاب کن و بهینه بنویس نیازی به این نوع بهینه سازی ها نیست !
MohsenB
دوشنبه 02 آبان 1390, 23:01 عصر
سلام
ممنون از نظرتون آقای تاجیک ولی
@ MohsenB : الگوریتمت رو درست انتخاب کن و بهینه بنویس نیازی به این نوع بهینه سازی ها نیست !
وقتی پای ملیونها محاسبه در ثانیه باشه حتما نیازه .
موفق باشید
Felony
سه شنبه 03 آبان 1390, 00:34 صبح
وقتی پای ملیونها محاسبه در ثانیه باشه حتما نیازه .
وقتی اینجوری میگی میلیون ها محاسبه در ثانیه ( اون هم پردازش تصویر ) جوابت میشه اینکه دلفی برای این کارها نیست ( نه از نظر قدرت بلکه از نظر کمبود منابع ، کمبود نمونه سورس ، کمبود کتابخانه های پردازش تصویر ) و به زودی با مشکل مواجه میشی ؛ در ضمن دوباره میگم با این توضیحاتی که دادی پروژه سنگینی رو در نظر داری و این نوع بهینه سازی ها که قوانین رو زیر سوال میبره بعد از مدتی که پروژه جلو رفت بدجور پشیمونت میکنه و به ضررت تموم میشه ! ( این تجربه منه ، بقیه رو نمیدونم ! )
MohsenB
سه شنبه 03 آبان 1390, 01:12 صبح
وقتی اینجوری میگی میلیون ها محاسبه در ثانیه ( اون هم پردازش تصویر ) جوابت میشه اینکه دلفی برای این کارها نیست ( نه از نظر قدرت بلکه از نظر کمبود منابع ، کمبود نمونه سورس ، کمبود کتابخانه های پردازش تصویر ) و به زودی با مشکل مواجه میشی ؛ در ضمن دوباره میگم با این توضیحاتی که دادی پروژه سنگینی رو در نظر داری و این نوع بهینه سازی ها که قوانین رو زیر سوال میبره بعد از مدتی که پروژه جلو رفت بدجور پشیمونت میکنه و به ضررت تموم میشه ! ( این تجربه منه ، بقیه رو نمیدونم ! )
در رابطه با منابع درسته شاید کم باشن ولی حستن . ولی من بیشتر الگوریتمها رو خودم پیاده میکنم و یا الگوریتم های موجود رو بزبون دلفی مینویسم .
من خودمم تعریف متغییر محلی رو قبول دارم همون طور که تئوریی هم که گفتم موافق همین بود . ولی در بعضی مواقع مثل حالتی که تو آزمایش دوستمون پیش اومد متغییر سراسری کارامدتره . خواستم از نظرات و تجربه های بقیه دوستان مطلع بشم .
tdkhakpur
پنج شنبه 05 آبان 1390, 18:48 عصر
فکر کنم یه بحث هایی در سطح سیستم عامل هست که میگه وقتی یه تابع صدا زده میشه که اون تابع توش یه متغییر ساخته میشه اون متغییر توی صفحه ای از حافظه قرار داده میشه که نزدیکتر به دستورات اون تابع هست ، پس وقتی اون صفحه به کش سی پی یو میره دستیابی بهش سریعتر انجام میشه . و اینجوری سرعت دسترسی به اون متغییر محلی از سرعت دسترسی به لود کردن صفحه ای دیگر و دستیابی به متغییر عمومی بیشتره .
ببین در حالت کلی کش cpu همان محدوده رجیسترها هستن فقط داخل cpu قرار دارن و اگه بخواهید تو این سطح برنامه بنویسید فرقی نداره که داده ها کجا باشن بالاخره بیشتر از اندازه این کش که میتونه 128 یا .. باشه نمیتوانید داده درش قرار بدید بحث اینجاست که شما برای دسترسی به محتوای ram از چه نوع کدی استفاده کنید اگه از delphi یا .. بجز اسمبلی استفاده میکیند نمیتوانید تشخیص بدید که برای دسترسی به محتوای حافظه چه آپ کدهایی انجام میگیره تا به داده ها دسترسی بشه پس برای این باید کار رو بسپارید دست کدهای اسمبلی تا از این طریق بتوانید نزدیکترین کد را برای دسترسی به داده ها بنویسید.
در ضمن وقتی از پشته کمک بگیرید متغییرها با اجرای تابع از اول ساخته میشن.
توابع بازگشتی رو مطالع کنید.
MohsenB
پنج شنبه 05 آبان 1390, 19:17 عصر
ببین در حالت کلی کش cpu همان محدوده رجیسترها هستن فقط داخل cpu قرار دارن و اگه بخواهید تو این سطح برنامه بنویسید فرقی نداره که داده ها کجا باشن بالاخره بیشتر از اندازه این کش که میتونه 128 یا .. باشه نمیتوانید داده درش قرار بدید
سلام ممنون از نظرتون
یکمی اشتباه گفتین :
کش سی پی یو های سری X86 معمولا دارای حد اقل دو سطح ( Level ) می باشد که به ترتیب هر چه به سی پی یو نزدیکتر باشد حجم آن کمتر است و درمقابل از سرعت بیشتری برخوردار می باشد ، مورد استفاده این نوع معماری این است که اطلاعات پرکاربردتر به حافظه نزدیکتر انتقال داده می شوند . روش انتقال این اطلاعات متفاوت است ، یکی از پرکاربردترین این روشها تکنیک صفحه بندی است . در این تکنیک اطلاعات درون حافظه های دور از سی پی یو بصورت صفحه صفحه به اندازه های مشخص طبقه بندی میشوند ، و بجای آوردن تکتک خانه های حافظه اطلاعات بصورت صفحه صفحه وارد کش می شوند که به این صورت احتمال وجود اطلاعات مورد نیاز بعدی سی پی یو در یک صفحه بیشتر میشود . و ... و حجم حافظه کش هم از مجموع این سطح ها بدست می آید .
اینجاست که شما برای دسترسی به محتوای ram از چه نوع کدی استفاده کنید اگه از delphi یا .. بجز اسمبلی استفاده میکیند نمیتوانید تشخیص بدید که برای دسترسی به محتوای حافظه چه آپ کدهایی انجام میگیره تا به داده ها دسترسی بشه پس برای این باید کار رو بسپارید دست کدهای اسمبلی تا از این طریق بتوانید نزدیکترین کد را برای دسترسی به داده ها بنویسید.
این حرفتون درسته ولی باید فرقی تو حالت کد هم داشته باشه . من دنبال اونم .
در ضمن وقتی از پشته کمک بگیرید متغییرها با اجرای تابع از اول ساخته میشن.
توابع بازگشتی رو مطالع کنید.
این حرفتونو نفهمیدم . من از پشته استفاده نمیکنم . توابع بازگشتی هم ربطی بکار من نداره و هم خیلی افزونگی و کندی حافظه پیش میاره .
بازم ممنون از نظرتون
موفق باشید
tdkhakpur
شنبه 07 آبان 1390, 18:32 عصر
مورد استفاده این نوع معماری این است که اطلاعات پرکاربردتر به حافظه نزدیکتر انتقال داده می شوند . روش انتقال این اطلاعات متفاوت است ، یکی از پرکاربردترین این روشها تکنیک صفحه بندی است . در این تکنیک اطلاعات درون حافظه های دور از سی پی یو بصورت صفحه صفحه به اندازه های مشخص طبقه بندی میشوند ، و بجای آوردن تکتک خانه های حافظه اطلاعات بصورت صفحه صفحه وارد کش می شوند که به این صورت احتمال وجود اطلاعات مورد نیاز بعدی سی پی یو در یک صفحه بیشتر میشود . و ... و حجم حافظه کش هم از مجموع این سطح ها بدست می آید .
نزدیک یا دور معنی نداره این اندازه کالاک پالسهاست که طول و بعد از اون زمان اجرا رو مشخص میکنه.
در ضمن تا اونجایی که میدانم اون صفحه بندی از 286 به بعد قرار داده شده و ارتباطی به cpu نداره و یه قسمتی از ram هست.
این حرفتونو نفهمیدم . من از پشته استفاده نمیکنم . توابع بازگشتی هم ربطی بکار من نداره و هم خیلی افزونگی و کندی حافظه پیش میاره .
منظور اینه که نحوه ساخت متغییر درون توابع رو بدونید اگر به اون نوع توابع نگاه کنید و آدرس متغییرها رو به کنسول پاس بدید تا نشونش بده در هر بار اجرا آدرس متفاوتی رو میده(البته نوع متغییر استاتیک نباید باشه)
MohsenB
شنبه 07 آبان 1390, 21:36 عصر
نزدیک یا دور معنی نداره این اندازه کالاک پالسهاست که طول و بعد از اون زمان اجرا رو مشخص میکنه.
در ضمن تا اونجایی که میدانم اون صفحه بندی از 286 به بعد قرار داده شده و ارتباطی به cpu نداره و یه قسمتی از ram هست.
بازم ممنون از نظرتون
منظور از دور و نزدیک اینه که تو یه سیستم با این معماریی که گفتم یه همچین ترتیبی برا حافظه ها وجود داره که هر چه به مرحله بعد از سی پی یو بریم از سی پی یو دورتر شدیم یا به عبارت دیگر از یک نظر فاصله فیزیکی از رم دورتره و در نتیجه سرعت انتقال هرچه دور تر باشه به علت دلایل زیادی کمتر میشود . این ترتیب برای یک کامپیوتر نمونه به این صورته :
[CPU] - Cache Level 1 - Cache Level 2 - Cache Level 3 - RAM - HDD Buf - HDD
تو این دسته بندی که هر حافظه که داخل پکیج جداگانه ای است بترتیب آبی -> سی پی یو ، صورتی -> رم و سبز -> هارد دیسک می باشد . هر چه به سی پی یو نزدیک تر باشد از سرعت بیشتری برخوردار است ولی حجم کمتری را توانایی ذخیره سازی دارد .
تکنیک صفحه بندی هم همینطور که گفتم به سیستم عامل ربط داره نه سی پی یو .
منظور اینه که نحوه ساخت متغییر درون توابع رو بدونید اگر به اون نوع توابع نگاه کنید و آدرس متغییرها رو به کنسول پاس بدید تا نشونش بده در هر بار اجرا آدرس متفاوتی رو میده(البته نوع متغییر استاتیک نباید باشه)
والا بدترش کردین ، دیگه اصلا نفهمیدم چی گفتین . میشه بیشتر توضیح بدین .
az-navaei
یک شنبه 15 بهمن 1391, 16:12 عصر
سلام
من تست را انجام دادم و دقیقا نتایج برعکس بود
در متغیر محلی 218 بود و در متغیر عمومی 702
یعنی با تعریف متغیر محلی سرعت بالاتر بود
cpu Core2 Duo T6670
32 bit
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.