Khaled Alshaya

هل تعرف ما فائدة ال Inline Functions في ++c ؟

30 ردود في هذا الموضوع

السلام عليكم ,,

فكرت في طرح موضوع حول الـ inline functions في المنتدى, و لكني تراجعت عن ذلك,

ما رأيكم بدلاً من ذلك أن نطرح مجموعة من النقاط و يتم التعليق على تلك النقاط ,,

طبعاً أنا كنت قد جهزت مجموعة من النقاط التي يمكننا التحاور حولها للخروج بالفائدة المطلوبة ,,

سنبدأ بكل نقطة و نفصل فيها و عندما ننتهي منها سننتقل إلى إلى النقطة التالية.

محاور الموضوع مكونة من ثلاث نقاط هي كالتالي :

- ما هي الـ Inline Functions و ما هو الفرق بينها و بين الدوال Functions العادية ؟

- هل تزيد الـ Inline Functions من سرعة البرنامج حقاً, و إذا كان ذلك صحيحاً فهل ينطبق هذا الكلام على جميع الحالات ؟

- خلاصة النقاش, متى يجب استخدامها و متى يجب تجنبها ؟

تحياتي ,,

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

سأبدأ بعد إذنكم بتعريفكم بالـ inline functions ,

سأبدأ بمثال بسيط جداً لتوضيح الفكرة فقط,

تصور أن لدينا الدالة التالية :

int sqr( int num ){
return (num * num);
}

الدالة تقوم بتربيع العدد المدخل لها ثم تقوم بإرجاعه, يمكن بالطبع استخدامها كالتالي في برنامجنا :

int x = sqr( 4 );

قيمة x هي 4*4 و تساوي 16, الآن ما فائدة هذا الكلام ؟

تصور أننا استخدمنا هذه الدالة في حلقة لتربيع 10000 رقم على سبيل المثال, بالطبع في كل مرة يصل تنفيذ البرنامج إلى الدالة, سيتم الإنتقال إلى الدالة و تنفيذ ما بداخلها ثم إرجاع القيمة إلى x,

بسيط جداً أليس كذلك !!

و لكن, أليس الذهاب للدالة في كل مرة ثم العودة للبرنامج الرئيسي أو الدالة التي استدعتها يستهلك وقتاً ليس له داعي أصلاً, فدالتنا بسيطة جداً!!!

الآن لننظر إلى دالتنا بعد أن أصبحت inline :

inline int sqr( int num ){
return (num * num);
}

كل ما قمنا به هو إضافة inline في البداية, و لكن ما هي الفائدة ؟

يمكنك استدعاء الدالة تماماً كما فعلنا في المرة السابقة, و لكن هذه المرة عند استدعاء الدالة, سيقوم المترجم (خلال عملية الترجمة طبعاً) بالتالي :

int x = x*x;

سيقوم باستبدال الدالة, ووضع x*x مباشرة, و بالتالي لم يعد هناك ذهاب و عودة من و إلى الدالة B) , كل مرة نقوم بتعريف الدالة على أنها inline سيقوم المترجم باستبدال اسم الدالة بالدالة نفسها !!

طبعاً مبرمجوا الـ C سيعترضون :D و يقولون أن يمكننا فعل نفس الشيء بالـ Macros, الحقيقة أن هذا خارج نطاق النقاش و لكن الـ inline functions في ++C تم استحداثها للتخلص من بعض المشاكل التي تحدث بسبب استخدام الـ Macros.

إلى هنا تنتهي الأنسة inline :D

ما رأيكم لو فصلنا قليلاً في عملية استدعاء الدوال العادية, و بالتالي يصبح لدينا فكرة أفضل عن سبب سرعة الـ inline functions.

أنا في انتظار مشاركاتكم ,,

تحياتي ,,

تم تعديل بواسطه Khaled.Alshaya
1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم ...

استخدام inline يزيد من حجم البرنامج فينبغي عدم استخدامها في الاجراءات الكبيرة

فقط استخدمها في اجراءات صغيرة مثل الذي عرضه الاخ خالد يزيد من اداء البرنامج.

فما هو اختيارك هل تفضل الاداء العالي ام الحجم الصغير؟

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أهلاً بك أخ garo ,,

استخدام inline يزيد من حجم البرنامج فينبغي عدم استخدامها في الاجراءات الكبيرة

فقط استخدمها في اجراءات صغيرة مثل الذي عرضه الاخ خالد يزيد من اداء البرنامج.

فما هو اختيارك هل تفضل الاداء العالي ام الحجم الصغير؟

جميل جداً, و لكن هذا ليس صحيحاً في كل الحالات فأحياناً الحجم سيكون تقريباً متساوي مع الأفضلية للـ inline بغض النظر عن حجم الدالة.

لنفهم سبب هذا الشيء, ما رأيكم لو فصلنا قليلاً في عملية استدعاء الدوال( بصورة عامة طبعاً, دون تحديد معالج معين) حتى نفهم العملية بشكل عام.

أنا في الانتظار

تحياتي ,,

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

الـ Inline Function هى اقتراح للمترجم و ليست كالدوال العادية ففى حال كبر حجمها قد تترجم كأنها دالة عادية.

الهدف من الـ Inline Function هو تسهيل عمل البرنامج اثناء تصميمه، و كما قال الأخ Khalid.Alshaya فالحجم النهائى للملف التنفيذى سيكون متقارب سواء استخدمناها ام لا.

و فى حالة الـ recursion أعتقد ان ستعامل معاملة الدوال العادية وقت الترجمه بسبب إستدعائها لنفسها عدة مرات.

و بالنسبة للأداء العالى و الحجم الصغير فالأداء العالى افضل بالطبع لإن الأن يوجد Hard Disk و Memory بأحجام كبيرة و بالتالى زيادة حجم البرنامج لن تأثر كثيرا لا على الذاكرة او حتى فى المساحة التخزينية.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
جميل جداً, و لكن هذا ليس صحيحاً في كل الحالات فأحياناً الحجم سيكون تقريباً متساوي مع الأفضلية للـ inline بغض النظر عن حجم الدالة.

اخي خالد انا متاكد ان حجم الكود يوثر في حجم البرنامج المخرج.

انظر الي هذه الدالة:

void scal( void* val){
if(!val) return (void*)0;
int a = 5;
int b = 10;
int c = 15;
int d =20;
int e =25;
int f = 30;
int g =35;
int h =40;
void* ret =(void*) ((int)val * a + (int)val *b + (int)val * c + (int)val *d +(int)val * e + (int)val * f + (int)val * g +(int)val * h);
return ret;
}

تحتوي علي الكثير من الاوامر ، هذه الاوامر بالطبع تزيد من حجم البرنامج عند ترجمتها.

فما بالك بوضع دالة كهذه inline واستدعائها في عدة مواضع من البرنامج سيتم كتابة نفس الاوامر في موضع استدعا الدالة هذه كارثة قد تحل بحجم البرنامج المخرج.

لكن دوال صغيرة مثل min/max فقط يمكن وضعها inline سوف يذيد من اداء البرنامج بشكل طفيف.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
لـ Inline Function هى اقتراح للمترجم و ليست كالدوال العادية ففى حال كبر حجمها قد تترجم كأنها دالة عادية.

اخي Game Expert السلام عليكم..

ان inline لن يتم ترجمتها الي دالة عادية في الوضع العادي مالم يتم تفعيل الخيار compiler optimization

و بالنسبة للأداء العالى و الحجم الصغير فالأداء العالى افضل بالطبع لإن الأن يوجد Hard Disk و Memory بأحجام كبيرة و بالتالى زيادة حجم البرنامج لن تأثر كثيرا لا على الذاكرة او حتى فى المساحة التخزينية.

انا اوافقك علي ان الاداء العالي افضل من الحجم الصغير.

لكن يجب الموازنة بينهما وعدم الاسراف في استخدام inline

كذلك عدم استخدام انواع بيانات كبيرة لمتغيرات قد لا تحتاج الي هذا الحجم الكبير مثل استخدام المتغير __int64 مع عدد الشهور في السنة فهذا استهلاك للذاكرة.

تم تعديل بواسطه garo
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أهلاً بك أخ Game Expert,,

و فى حالة الـ recursion أعتقد ان ستعامل معاملة الدوال العادية وقت الترجمه بسبب إستدعائها لنفسها عدة مرات.

هذا الكلام اللي يفرح الواحد :D

ما دام أننا عرفنا الـ inline functions, و ذكر الأخ Game Expert أن المترجم يحولها إلى دالة عادية إذا كانت recursive, لنستعرض قليلاً عملية استدعاء الدوال العادية,

عند الوصول إلى أمر استدعاء الدالة, في مكان ما في الذاكرة يسمى الـ stack ,,

يتم وضع وسائط الدالة arguments على الـ stack ليتم تجهيزها للدالة, ثم يتم وضع عنوان السطر الذي تم استدعاء الدالة منه في البرنامج الرئيسي,

بعد ذلك يتم الانتقال للدالة لتنفيذها, ستقوم دالتنا بحساب شيء مطلوب منها طبعاً, بعد ذلك ستقوم بإعادته في منطقة تخزينية في المعالج (هذا يعتمد على المعالج نفسه), و بعد ذلك في عبارة الـ return تحديداً سيقوم المعالج بالنظر إلى العنوان الذي وضعناه مسبقاً على الـ stack, لكي يعرف إلى أي سطر يعود, بالطبع هذه هي كل العملية بشكل مبسط جداً,

كل ما يهمنا في العملية السابقة طبعاً هو عملية وضع الوسائط على الـ stack, و التي تتم كل مرة يتم استدعاء الدالة فيها,

أما في الـ inline functions فلا يتم شيء مما ذكرناه في حالة الدوال العادية :blink:

بالتالي لو كانت الدالة تستدعي نفسها recursive, فإن الوسائط( في الحقيقة هي ليست وسائط) هي نفسها التي تتعامل معها الدالة الـ recursive كل مرة يتم استدعاء الدالة و بالتالي تحصل المصيبة :D

لهذا لا تسمح المترجمات بجعل الدالة inline إذا كانت recursive ,,

لنتكلم الآن عن الحالات التي يمكن للـ inline functions أن تزيد من سرعة البرنامج دون التأثير على حجمه (بشكل كبير طبعاً),

تحياتي ,,

تم تعديل بواسطه Khaled.Alshaya
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أخ garo الحجم لن يزيد الا اذا تجاوز الكود حجم الـSectionAlignment لقسم الكود , ولتتأكد بنفسك انظر الاصفار بعد نهاية الكود في قسم الكود ...

فقط اذا تجاوز هذا الحجم يتم اضافة مقدار SectionAlignment الى قسم الكود

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم:

------------------------------

الرد على المبرمجين بلغة C في حالة لو حاولوا يعملوا مقارنة بين الإجراءات الخطية Inline Functions و الماكرو Macro فسيكون هناك كلمة واحدة فقط وهي "الأمان" وكلنا نعرف الأمان نعمة الرحمن ولازم نحاول الحفاظ والحصول عليها حتى في إنشاء البرامج.

الماكرو غير آمن لأنه رح يكسر اكبر ميزة بلغة ++C وهي أنها لغة قوية بيانياً Strongly-Typed Language. صحيح انا قادرة اكتب شيفرة مكعب العدد بطريقة الماكرو كالتالي

#define unsafeCube(x) (x * x * x)

لكن يا ترى شو الحرف x هذا وهل هذه الطريقة آمنة أو لا؟

لكن بتعيين وتحديد نوعية البيانات المسترجعة من الأجراءات بصفة عامة (العادية أو الخطية) وتحديد نوعية البيانات الممرة داخل الإجراء ,,جوهر القوة في لغة ++C.

ملاحظة:

بالمناسبة أي إجراء داخل الطبقة class يحتوي على جسد وهو كل ما بين الاقواس {...} سيُعامل كما لو انه إجراء خطي inline function وهذه المعاملة ستكون ضمنياً عند تنفيذ البرنامج حتى بدون كتابة مفتاح الكلمة inline.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أهلاً GamingMasteR,,

أنت مبرمج ++C بالفطرة صدقني :P

اترك الاسمبلي و تعال معانا :D

مع أن الكلام ليس موجه لي, و لكن أحب أن أجيب عن هذه النقطة,

أخ garo الحجم لن يزيد الا اذا تجاوز الكود حجم الـSectionAlignment لقسم الكود , ولتتأكد بنفسك انظر الاصفار بعد نهاية الكود في قسم الكود ...

فقط اذا تجاوز هذا الحجم يتم اضافة مقدار SectionAlignment الى قسم الكود

الحجم سيزيد في كل مرة نستدعي الدالة في مكان مختلف من الكود, لأن كود الدالة سينسخ بدلاً من استدعاء كود الدالة في الحالات العادية,

حتى أكون معكم صريحاً, أنا لا أستخدمها غالباً, و لكن الذي أراه في أكواد المبرمجين أنهم يستخدمونها في حالات معينة,

على سبيل المثال في حلقة حيث تستدعى الدالة في مكان واحد أو اثنين في البرنامج ككل,

الحالة الأخرى, هي في الـ scientific libraries حيث السرعة هي الأهم غالباً, و غالباً هذا النوع من المكتبات يتم تصميمه على أيدي مبرمجين محترفين, بالتالي تتم الاستفادة القصوى من المفهوم,

الأخت رغد طرحت لنا جانباً جديداً في العملية ,, بالطبع مشكورة على مشاركتها ,,

الرد على المبرمجين بلغة C في حالة لو حاولوا يعملوا مقارنة بين الإجراءات الخطية Inline Functions و الماكرو Macro فسيكون هناك كلمة واحدة فقط وهي "الأمان" وكلنا نعرف الأمان نعمة الرحمن ولازم نحاول الحفاظ والحصول عليها حتى في إنشاء البرامج.

الماكرو غير آمن لأنه رح يكسر اكبر ميزة بلغة ++C وهي أنها لغة قوية بيانياً Strongly-Typed Language.

كلام في الصميم, و هذا الكلام مع أنه متقدم حبتين, إلا أن هناك طريقة في ++C أفضل من الـ Macros بمراحل, و هي بكل بساطة الـ templates ,

هل تخيلتم التركيبة الكيميائية :D

حيث ستكون الدالة inline template function :thumbup:

هذا بالطبع من عجائب ++C و لا يحلم به مبرمجوا اللغات الأخرى و لو وصلوا للقمر و رجعوا :D

تحياتي,,

تم تعديل بواسطه Khaled.Alshaya
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
ان inline لن يتم ترجمتها الي دالة عادية في الوضع العادي مالم يتم تفعيل الخيار compiler optimization

غير صحيح اخى العزيز فلو حاولت صنع دالة مثل التى صنعها الأخ Khalid.Alshaya فسيصبح تحويل الدالة من inline إلى normal امر أضطرارى و ليس اختيارى ؟ و إلا ما شكل الكود الذى سيتم نسخه مكان إستدعاء الدالة!!

و الله ولى التوفيق

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
غير صحيح اخى العزيز فلو حاولت صنع دالة مثل التى صنعها الأخ Khalid.Alshaya فسيصبح تحويل الدالة من inline إلى normal امر أضطرارى و ليس اختيارى ؟ و إلا ما شكل الكود الذى سيتم نسخه مكان إستدعاء الدالة!!

حسناً ،هذه هي دالة الاخ خالد:

int sqr(int num)
{

return (num *num);
}

بعد ترجمتها الي لغة اسمبلي (يبدو انك مبرمج اسمبلي) .ليس لدي خبره كبيرة في الاسمبلي فقد تركتها منذ زمن لكني استعطيع ان

اوضح بها بقدر المستطاع.

asm {
push eax;

mov eax ,[num];
mov ecx ,[num];
mul eax,ecx;

mov [x],eax;

pup eax;
}

ثم يتم استدعاء الدالة هكذا:

int main (int)
{
int x = 3;


int y = sqr(x);
int z = sqr(x);

.
.
.
.
return 0;
}

بعد ذلك سيكون وضع الكود هكذا:

int main (int)
{
int x = 3;


int y;
asm {
push eax;

mov eax ,[x];
mov ecx ,[x];
mul eax,ecx;

mov [y],eax;

pup eax;
}


int z;
asm {
push eax;

mov eax ,[x];
mov ecx ,[x];
mul eax,ecx;

mov [z],eax;

pup eax;
}


.
.
.
.
return 0;
}

تم تعديل بواسطه garo
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم,,

أهلاً بالمحاربين من جديد :D

النقاش اشتعل و لا أحلى,,

أخ garo, أعتقد أني فهمت ما تقصد بـ :

ان inline لن يتم ترجمتها الي دالة عادية في الوضع العادي مالم يتم تفعيل الخيار compiler optimization

كلامك صحيح, و لكن أي Optimization تقصد ؟

هذه الـ Optimizations المتوفرة في ++g لدي (أنا أعمل على codeblocks) :

post-89451-1199536485_thumb.png

كما ترى هناك أنواع كثيرة اثنين للحجم و غيرها للسرعة, أعتقد (لم أجرب بعد) لو أنني فعلت الـ Optimization الذي يشير له السهم الأحمر الثاني فسيتم تحويل الدوال الـ inline إلى دوال عادية إذا تم استدعائها من عدة أماكن مختلفة,

أما إذا فعلنا الـ speed Optimizations فلن يتم التحويل,

على كل حال, الدوال الـ inline ليس من المفترض أن تحل محل الدوال العادية, و لكنها عملية مقايضة trade offs بين استدعاء دالة صغيرة كل مرة أو دمج الكود الخاص بها مباشرة,,

تحياتي لك أخ garo ,,

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أخى garo انظر معى لهذا المثال

inline int factorial(int x)
{
if (x==0) return 1;
return x * factorial(x-1);
}

الدالة السابقة هى inline function

سوالى هو هل الدالة السابقة ستعامل وقت الترجمة على انهاء Inline و لا Normal ؟

و الله ولى التوفيق

تم تعديل بواسطه Game Expert
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم ,,

تم ذكر الـ recursive functions في الموضوع, و الحقيقة أن الموضوع معقد على الأقل بالنسبة لي :wacko:

أنا ذكرت أن المترجم يحولها إلى دالة عادية, هذا طبعاً بشكل عام,

ما رأيكم لو ركزنا على الـ inline recursive functions, لأنه الموضوع صراحة جميل,

سأضع ما لدي, و لكن بعد فاصل قصير ,,

تحياتي ,,

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

كنت في السابق طرحت موضوع في قسم الدلفي حول ال Inline functions, فقط لربط الاقسام ببعضها و يكون خبز و ملح بين أقسام المنتدى:)

Inline directive

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
سوالى هو هل الدالة السابقة ستعامل وقت الترجمة على انهاء Inline و لا Normal ؟

نعم اوفقك اخي Game Expert ان الدالة التي كتبتها تترجم علي انها دالة عادية لانها تستدعي نفسها (وهذا هو السبب الوحيد الذي يجعلها دالة عادية).

لكني اقصد الدوال inline (التي لا تستدعي نفسها) لن يتم تحويلها الي دالة عادية الا اذا تم تفقعيل الخيار Optimization وفي الحالات التالية فقط:

(1) كان حجم الدالة كبير

(2) سرعة تنفيذها بطيئة

كما ترى هناك أنواع كثيرة اثنين للحجم و غيرها للسرعة, أعتقد (لم أجرب بعد) لو أنني فعلت الـ Optimization الذي يشير له السهم الأحمر الثاني فسيتم تحويل الدوال الـ inline إلى دوال عادية إذا تم استدعائها من عدة أماكن مختلفة,

اخي خالد...

سيتم التحويل لكن بشروط كما وضحتها في الاعلي.

ستجد معلومات اكثر في تعليمات المترجم (انا لا استخدم gcc)

تم تعديل بواسطه garo
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

مرحبا أخ garo ( يشرفني أن أعرف اسمك أخي العزيز ) :)

لاحظ أخي العزيز أنك تتكلم عن تصرف الـ VC فقط, و هذا يعتمد على المترجم,

عملية التحويل تعتمد على نوع الـ Optimization الذي تريد تطبيقه على الكود, زيادة السرعة على حساب الحجم أو العكس,

عملية التحويل ليست إجبارية أيضاً في حالة الدوال الكبيرة, هناك خيار في ++g على ما أذكر يجبره على إبقاء الـ inline functions كما هي دون تحويل إلى دوال عادية ( كما قلت لك سابقاً الحكاية تعتمد على المترجم في هذا النوع من الأمور ).

الحقيقة لم أفهم ماذا تقصد بالتالي :hmm:

(2) سرعة تنفيذها بطيئة

إضافة إلى ذلك أخ garo, صحيح أني ذكرت أن الدوال الـ recursive يتم تحويلها إلى دوال عادية إذا كانت inline, و لكني تجنبت ذكر بعض التفاصيل لأن هذه هي الحالة العامة ,,

للأسف هذا الموضوع ليس بالسهل :( ( أقصد الـ inline recursive functions ),

هناك الكثير من الأمور المتقدمة التي يمكن للمترجمات فعلها في حالة inline recursive functions, لدي القليل حول الموضوع و هو بشكل عام نظرة أولية ليس أكثر,

يمكنني ذكر بعض تلك التقنيات المستخدمة إذا أحببت :rolleyes:

تحياتي ,,

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

مرحبا اخي خالد.

( يشرفني أن أعرف اسمك أخي العزيز )

بل يشرفني اكثر وجودك في هذا المنتدي واستفادتي من خبراتك. اسمي ( امين عمر )

بالنسبة الي سرعة الدالة فان مترجم ذكي مثل VC او GCC يستخدم طريقة لمعرفة سرعة الدالة تعتمد علي كمية الاوامر الموجودة في الدالة.

عندما تكون الدالة inline ولكنها تحمل الكثير من الاوامر فان المترجم في حالة Optimization يحولها الي دالة عادية

كذلك الدالة العادية يمكن ان تحول الي inline (تسمي هذه العملية auto-inlining)

هنالك خيارات كثيرة للـOptimization منها:

تحسين الـLoop.

تحسين عمليات الـ floating-point

تم تعديل بواسطه garo
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أهلاً بك أخ أمين :)

كذلك الدالة العادية يمكن ان تحول الي inline (تسمي هذه العملية auto-inlining)

:thumb_up: , أعرف أنها تطبق غالباً على الـ members of classes,

هنالك خيارات كثيرة للـOptimization منها:

تحسين الـLoop.

100 %,

على سبيل المثال لا الحصر كمثال بسيط :

for( int i = 0; i < 10; i++ ){
for( int n = 0; n < 10; n++ )
cout << "Inner Loop Output";
}

معظم المترجمات ستقوم بإلغاء عمق الحلقات و ستحولها للتالي :

for( int i = 0; i < 100; i++ )
cout << "Inner Loop Output";

بالطبع أخيراً نأتي على الـ recursive functions :huh:

هناك مترجمات تسمح بهذا الشيء, إحدى الطرق التي تستخدمها المترجمات هي تحويل الـ recursive calls إلى flat code, هذه العملية تعني أن كود الدالة سوف يتم دمجه في كود الدالة نفسه :blink:

بالطبع, سيكون الدمج إلى عمق معين فقط :rolleyes: , قد يقوم المترجم على سبيل المثال بتحويل الاستدعاء الأول إلى inline code ثم يقوم باستدعاء الدالة بشكل طبيعي, بالتالي حول أول استدعاء إلى inline و باقي الاستدعاءات تعامل على أنها دوال عادية,

لاحظ أنني لم أقل أن هذا سيزيد من الأداء في برنامجنا, بل على العكس إجبار المترجم على فعل ذلك إلى عمق كبير في الدالة الـ recursive, سيؤدي إلى إنقاص الأداء بشكل ملحوظ إضافة إلى زيادة حجم الكود بشكل رهيب :hmm:

و السبب أن الوصول إلى الذاكرة سيستهلك وقتاً أكبر من استدعائها بالطرق العادية, خصوصاً عندما تكون الدالة "العادية" في الـ cache الخاص بالمعالج. هذا سيؤدي إلى تحميل الكود كل مرة من الذاكرة إلى المعالج,

حسناً الحكاية لا تنتهي هنا :D , حتى بعد تحويل الـ recursive calls إلى flat code, سيزيد الحجم بشكل كبير كما ذكرت سابقاً, و لكن المترجمات ستقوم بعملية Optimization للكود الناتج من جديد :D

تحياتي أخي أمين ,,

تم تعديل بواسطه Khaled.Alshaya
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

الى فهمته ان الداله السياقية تستخدم اذا الكود قصير وبسيط.

لكن اعتقد انه ليس من الضرورة استخدام الداله السياقيه الا في النادر.

هل من الممكن معرفه هل المصرف راح يعتبرها سياقيه ام لا؟

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

بصراحة مواضيعكم جدا مفيدة خصوصا لنا يالمبتدئين في السي بلس بلس لكن انتم ماوضحتوا الان لاين فونكشن كثيروهي اللي الى الان مافهمتها واذا عندكم فكرة الاستاك لان استاذنا عطانا الفكرة وبس :clapping: وانا ابي توضيح اكثر عنه ويعطيكم العافية شباب

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

حقيقة موضوع قوي ومشاركات اقوى..

حتى لا تكون مشاركتي من نوع مشكووووووووور اضع تعليق بسيط رغم خبرتي المتواضعة فى البرمجة الكائنية..

inline تعتبر مجرد اقتراح قد يقبلها المترجم او قد يرفضها, فهى ليست اداة اجبارية, وفى حالة الrecursion فى الغالب اى مترجم يحترم نفسه سوف يقوم بإلغائها لانها قد تستهلك الذاكرة بشكل كبير جداً..

هناك directive اسمه rdepth تستطيع من خلاله تحديد عدد المرات التى تريد من المترجم ان يستخدم فيها inline فى حالة الrecursion على سبيل المثال إذا كانت الدالة تقوم باستدعاء نفسها 10 مرات وقمت انت بتحديد rdepth(2) فسوف يقوم المترجم باستخدام inline المرتين الاولى وباقي الثماني مرات يقوم باستخدام الاستدعاء الذاتي..

والسلام عليكم

تم تعديل بواسطه احمد غريب
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم ,,

الله ينور عليك يا أستاذ أحمد ,,

هناك directive اسمه rdepth تستطيع من خلاله تحديد عدد المرات التى تريد من المترجم ان يستخدم فيها inline فى حالة الrecursion على سبيل المثال إذا كانت الدالة تقوم باستدعاء نفسها 10 مرات وقمت انت بتحديد rdepth(2) فسوف يقوم المترجم باستخدام inline المرتين الاولى وباقي الثماني مرات يقوم باستخدام الاستدعاء الذاتي..

جميل جداً أن نرى خبراء المنتدى في قسمنا ,,

إن أعطانا الله العمر, سنلقي نظرة على الـ inline template functions و هي عبارة عن بديل كامل للـ Macros في الـC و لكنها توفر الـ type safety الذي لا يوجد في الـ Macros,,

تحياتي ,,

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
زوار
This topic is now closed to further replies.

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .