سه نکته برای بالا بردن سرعت

RainDigital

Member
با اینکه انجمن رو ترک کرده بودن و دو سه سالی میشد که هیچ کاری با هیچ جای مجید آنلاین نداشتم(بخاطر موضوعی که با بی منطقی محض مدیران حق من پایمال شد) ولی اخیرا چند بار اومدم و دیدم که انجمن php واقعا راکد و مزخرف شده(oop خوابیده، smarty خوابیده ، سوالات یا شده درخواست اسکریپت آماده اونهم با عنوان های این مدلی:"کمممممممممممممممممممممممممممممممممممک لطفا کمممممکم کنید" و دیگر سوال ها بسیار سطحی و مبتدی) برای همین مطلب کوچکی که به تازگی نوشتم، از وبلاگم اینجا کپی می‌کنم:


سلام.

امروز که دارم این مطلب رو می‌نویسم(11 تیر 1389 3:30، ب.ظ) بر مشکل عظیمی فائق آمدم! مشکلی که مدت‌ها با آن دست و پنچه نرم می‌کردم.

template compiler ای نوشته بودم برای یک cms. این قطعه برنامه به قدری کند عمل می‌کرد که از مرز 30 ثانیه هم می‌گذشت و با خطای
کد:
Fatal error: Maximum execution time of 30 seconds exceeded in F:\Program Files\EasyPHP 2.0b1\www\…\libs\templateengine.class.php on line xxx
مواجه می‌شدم. فکر کنید اگر کسی می‌خواست این cms رو با اینترنت ذغالی ببینه چی می‌کشید…

اما فقط با رعایت سه نکته ساده سرعت اجرا رو به حد لحظه ای رسوندم.
(1): بیجا از ” بجای ‘ استفاده نکنید

مفسر php محتوای بین دو ” ” را تجزیه و تحلیل می‌کند که اگر در آن متغیری بکار رفته بود مقدار آن را جایگزین کند. شما در یک فایل php ممکن است صدهابار از ” استفاده کنید بدون اینکه نیاز باشد و دست کم 3-4 کیلوبایت داده را بی جهت parse کنید. تعویض بجای ” با ‘ می‌تواند 1 الی 3 ثانیه زمان اجرا را بهبود ببخشد.

مثال ها:
درست نادرست
require ‘mysql.class.php’; require “mysql.class.php”;
echo ‘<header>’; echo(“<header>”);
$res['post_title']; $res["post_title"];
require “mod-$module.php”; require ‘mod-$module.php’;

(2): وقتی می‌شود از prinft و sprintf استفاده نکرد از آنها استفاده نکنید!

پیوندزدن رشته ها با .(نقطه-dot) بسیار سریع تر از printf و sprintf انجام میپذیرد. “$var1 $var2″ هم که به کلی روش غلطی است.

البته در اندک مواردی این دو تابع برنامه را خیلی خواناتر می‌کنند که کُندی این توابع قابل چشم‌پوشی است.

و هرگز از print استفاده نکنید! print یک تابع است اما echo تابع نیست بلکه یک دستور است.(مثل if, switch,function,…) فراخوانی یک تابع عملیاتی است که بسیار زمان بر تر از فراخوانی یک دستور است.درضمن شما با echo میتوانید کدی به این شکل بنویسید:

PHP:
echo 'Yourname is: ',$name,' - and lastname is: ',$lastname;
But when you Use print:
PHP:
 print ('Yourname is: ' . $name . ' - and lastname is: ' . $lastname);

در قطعه کد بالا استفاده از echo به همراه ویرگول ها هم راحت تر است و هم سریع تر از پیوند زدن رشته ها عمل می‌کند.

وقتی شما از echo استفاده می‌کنید، در سرور تابعی (این یک تابع php نیست بلکه تابعیست که با زبان C در شرکت zend نوشته شده است) صدا زده می‌شود تا عبارتی که جلوی echo نوشته شده را به مرورگر بفرستد. ولی وقتی شما از print استفاده می‌کنید، سرور در بین توابع php دنبال تابع print می‌گردد و وقتی آن را پیدا کرد، محتوایش را می‌خواند و دستورات آن را که به زبان php اند اجرا می‌کند. این دستورات مانند echo آرگومان تابع را به مرورگر می‌فرستند. حالا مسئله خروج از تابع باقیست!!
(3): هرگز از ereg_replace استفاده نکنید

سه چهار ثانیه را با دو نکته قبل حل کردم. اما امان از ereg_replace که از آن برای پیدا کردن متن بین دو تگ استفاده می‌کردم! قبلا اینطور کار می‌کردم:
PHP:
$post_template = eregi_replace("(.+)(<\\\$post\\\$>)(.+)(<\\\$\/post\\\$>)(.+)","\\3",$compiled);
و حالا:
PHP:
class templatecompiler
.
.
>.
// get the content between tags
private function __gettag($tag)
{
$tag1 = "<$$tag>";
$tag2 = "<$/$tag>";
$text = $this->compiled;
$tag1_len = strlen($tag1);
$seek1 = strstr($text, $tag1);
$seek2 = strstr($text, $tag2);
if($seek1 & $seek2)
{
$pos1 = strpos($text, $tag1);
$pos2 = strpos($text, $tag2);
$split_len = $pos2 - $pos1;
$text = substr($text, $pos1, $split_len);
$text = substr($text, $tag1_len);
return $text;
}
}
.
.
.
$post_template = $this->__gettag('post');
.
.
.
}
?>
سرعت به شدت بالا رفته است!

درضمن قطعه قطعه کردن برنامه و نوشتن کلاس بسیار در وقت کاربر، گسترش دهنده و برنامه نویس صرفه جویی می‌کند.

پ.ن: در کد های وردپرس نکته 1 فقط در بعضی جاها رعایت شده که متاسفانه باعث می‌شود حتی در لوکال هوست(localhost) تاخیری نزدیک به 1 ثانیه داشته باشیم.البته در بعضی جاها هم رعایت شده. شاید این بخاطر این باشد که هسته وردپرس را یک نفر ننوشته بلکه یک تیم با سواد برنامه نویسی یا بهتر بگم دقت در برنامه نویسی نابرابر.

موفق باشید.

پایان




منبع: http://raindigital.wordpress.com/2010/07/03/speed-up-php-programs
 

maysam.m

Well-Known Member
خوشحالم از بازگشت مجددتون به م.آ
مقاله بسیار خوبی بود.
امیدوارم همانطور که گفتید بخش پی اچ پی دوباره پرشور تر بشه تا امثال من از وجود دوستانی مثل شما نهایت استفاده را بکنند هر چند که مدیر جدید بخش به خوبی فعالیت میکند و اگر کم کاری هم باشد از کاربرانی (مثل من!) است!

موفق باشید.
 

eAmin

Well-Known Member
سلام

من به هیچ چیزی کار ندارم، فقط درمورد ereg_replace که شما گفتید یک چیز رو باید گفت و اون هم اینه که: درسته این تابع سرعت رو کمی پایین می یاره، ولی در اکثر مواقع اشتباه از خود برنامه نویس و کسی هست که پترن مربوطه برای پیدا کردن یک مورد خاص در رشته بکار می بره!

مثلن در همین مثالی که شما گذاشتید، به نظر من نه تنها بهینه نیست، بلکه بدترین نوع پترن موجود مخصوصا برای کارهایی که قراره در سرور انجام بشه هست!
ببینید، اگر ما با آشنایی کامل یا متوسط با Reqular Experssion یک پترن مناسب و بهینه بنویسیم، مطمئن باشید سرعت قابل قبولی دریافت خواهیم کرد و احتمال اینکه با چنین مشکلاتی روبرو بشیم خیلی کم می شه.

موفق باشید.
 
آخرین ویرایش:

farik

Well-Known Member
با سلام..بابت مقاله واقعا ممنون...بيش از حد مفيد بود..اميدوارم مقالهاتون هر روز پربارتر بشه...
سلام

من به هیچ چیزی کار ندارم، فقط درمورد ereg_replace که شما گفتید یک چیز رو باید گفت و اون هم اینه که: درسته این تابع سرعت رو کمی پایین می یاره، ولی در اکثر مواقع اشتباه از خود برنامه نویس و کسی هست که پترن مربوطه برای پیدا کردن یک مورد خاص در رشته بکار می بره!

مثلن در همین مثالی که شما گذاشتید، به نظر من نه تنها بهینه نیست، بلکه بدترین نوع پترن موجود مخصوصا برای کارهایی که قراره در سرور انجام بشه هست!
ببینید، اگر ما با آشنایی کامل یا متوسط با Reqular Experssion یک پترن مناسب و بهینه بنویسیم، مطمئن باشید سرعت قابل قبولی دریافت خواهیم کرد و احتمال اینکه با چنین مشکلاتی روبرو بشیم خیلی کم می شه.

موفق باشید.
راستش من هم تا حدي موافقم اما اينكه ياد بگيري پترن مناسب بنويسي رو راستش من جايي نديدم...يادمه 1-2 سال پيش كه ميخواستم خود پترن نويسيش رو ياد بگيرم پدرم در اومد البته حالاش رو نميدونم...بازم خوشحال ميشم اگه يك منبعي چيزي در مورد چگونگيبهينه نويسي پترن ها بهم معرفي كنيد:wink:
با تشكر TabOTabDesign
 

eAmin

Well-Known Member
اول بزارید از مشکلات پترن موجود بگم.
در این پترن ( الگو ) شما از 5 پرانتز باز و بسته استفاده کردید، که به اونها زیر عبارت میگن. کار این پرانتز ها رو می دونید؟ کاربرد این پرانتزها در چندین مورد هست که مهمترین کاربرد این زیر عبارتها، گروه بندی و ذخیره مقدار پیدا شده در یک آرایه هست. همونطور که مشخصه شما در پترن مورد استفاده تون 5 بار از این زیر عبارتها استفاده کردید و شما پترن رو وادار می کنید که هرچیزی که دید وارد آرایه کنه، مثلا این مثال رو ببنید که شما چندین بار از اون در پترنتون استفاده کرده بودید!
کد:
(.+)
خب کار پترن بالا اینه که هرچیزی که در مقدار ورودی وجود داشت، رو برای ما در یک آرایه ذخیره کنه! و جالبترش اینجاست که این عمل چندین بار در یک پترن انجام شده! و حالا می دونید که همین پترن نیم وجبی(!) چقدر process رو در سرور هدر می ده؟ خب حالا خودتون نتیجه گیری کنید، آیا این پترن مناسب کاری مثل استفاده در template engine است؟

راستش من هم تا حدي موافقم اما اينكه ياد بگيري پترن مناسب بنويسي رو راستش من جايي نديدم...يادمه 1-2 سال پيش كه ميخواستم خود پترن نويسيش رو ياد بگيرم پدرم در اومد البته حالاش رو نميدونم...بازم خوشحال ميشم اگه يك منبعي چيزي در مورد چگونگيبهينه نويسي پترن ها بهم معرفي كنيد
خب دلیلش این می تونه باشه که فکر میکنم کمتر کسی با عبارات باقائده آشناست، یا شاید تعدادشون بالا باشه ولی کمتر این موضوع رو برای دیگران روشن می کنند. درضمن اگر در نوشتون پترن سعی کنید موارد مختلف رو امتحان و جستجو کنید و با تمرین جلو برید ناخودآگاه با این موارد آشنا می شید، که چه پترنی مناسب و یا نامناسب است.
به نظر من بنظر من یادگیری عبارات باقائده بسیار ساده است، فقط کمی نیاز به تمرین و پشتکار داره.:wink:

پترنی که نوشته بودم چطوری باید اصلاح شه؟
البته بگذریم که کلا ereg جماعت دیگه پشتیبانی نمی شه، من در ساده ترین حالت این الگو رو نوشتم، همینجا اعلام می کنم که این پترنی که نوشتم صرفا بهینه ترین نیست.
کد:
$post_template = preg_replace('#<\$post\$>([\s\S]+)<\$post\$>#gi', '$1', $compiled);

موفق باشید.
 
آخرین ویرایش:

S.A.N

Member
سلام بابت کد ممنون

من استفاده کردم

برگشتت هم را به فال نیک میگیریم !؟!؟!؟ :green: (چی گفتم)
 

جدیدترین ارسال ها

بالا