الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

سؤالين عن السرعة في التعامل مع ال Stack , Heap

بدأه HaTy في 21 مارس 2009 · 9 رد · 862 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

بســم الله الـرحمــن الرحيــم

السلام عليكــم ورحمـة الله وبركاتــه ،،

اخواني الاعزاء لدي سؤالين يرجى الاجابة عنهما

السؤال الاول : ايهما اسرع في التطبيق الحجز من الـ Stack او Heap ؟

مثلا

char testString[10];

او

char *testString = new char[10];

السؤال الثاني : لو عندنا تركيب بيانات ما مثلا هذا التركيب


{
int ID;
string name;
};
struct TestStruct

فايهما اسرع في التعامل


ts.id = 10;
ts.name.c_str() = "arabteam";
TestStruct ts;

او


ts->id = 10;
ts->name.c_str() = "arabteam";
TestStruct *ts;

مع شكري المسبق

تحياتي

تم تعديل هذه المشاركة بواسطة haty في 21 مارس 2009 في 15:46

while( "اسلام" )
{
 cout >> "الموت لبني صهيون" >> endl;
}
return "فلسطين";
#2

السلام عليكم ورحمة الله وبركاته

الحجز من الstack يتم اثناء الcompilation لذلك اعتقد انه يكون اسرع

بينما الحجز من heap يكون اثناء التنفيذ run-time ويقوم باستدعاء اكثر من دالة للوصول الى النظام لذلك اظنه ابطأ

لكن اذا كانت الذاكرة التي تريد حجزها كبيرة فيفضل استهلاك الheap عن الstack حتى لا يحدث stack overrun

#3

بالنسبة للسؤال الثاني فالشكل الثاني للكود لم يتم فيه حجز الstructure لكن لا مشكلة سنفترض انه تم ذلك :)

الأمر يختلف تبعا للذاكرة التي بها الstructure

اذا كانت موجودة في عنوان محدد مسبقا كالglobal variables فان استخدام المؤشر ابطأ غير ذلك فلا فرق

#4

شكرا اخي Mudokon على التفضل بالاجابة

هذا ما اعتقدته ايظا

تبقى اجابة السؤال الثاني , وان كنت اضن ان التعامل مع المؤشرات اسرع

تحياتي

while( "اسلام" )
{
 cout >> "الموت لبني صهيون" >> endl;
}
return "فلسطين";
#5

في مثالك الأول فإن الحجز من الـ Stack أسرع,

بشكل عام فإن استخدام المؤشرات أبطأ بقليل من استخدام الـ automatic storage variables....

لأننا نقوم بعملية Indirection و هي تقابل تعليمة دائماً في لغة Assembly... المؤشرات ليست لهذه الأغراض التي تتكلم عنها....

في مثالك الثاني أيضاً فإنك قد خلطت الموضوع...

الصحيح هو التالي ::

TestStruct ts;
ts.id = 10;
ts.name = "arabteam";

و الثاني ::

TestStruct *ts;
ts->id = 10;
ts->name = "arabteam";

الموضوع كبير جداً و هناك حالات كثيرة جداً, عليك بالقراءة عن موضوع الـ Call Stack و لماذا نستخدم ما يسمى بالـ Stack في تخزين متغيراتنا, الذاكرة لو نظرنا إليها ما هي إلا Heap و نحن قمنا ببناء الـ Stack فوقها سواء عن طريق الـ Hardware كما تفعل معظم المنصات الحديثة و غالباً يسمى Stack Pointer... أو بمحاكاة الموضوع في برنامجنا...

ماهي الفائدة التي نجنيها من استعمال ما يسمى بالـ Call Stack ؟! إذا حللت السؤال .. فستفهم أيضاً أن الـ Recursion ما هو إلا Loop و لكن الـ Stack الخاصة بالـ Recursion يتم تنظيمها أوتوماتيكاً بينما نقوم بمحاكاتها يدوياً في الـ while loop على سبيل المثال..

ببساطة هناك افتراض نفترضه عندما نبرمج في أي لغة برمجة عالية المستوى (أعتقد, إذا كانت ظهرت بعد الخمسينيات :) ) و ذلك عند كتابة برامجنا و سببه استعمالنا للـ Stack ...!

#6

بســم الله الـرحمــن الرحيــم

السلام عليكــم ورحمـة الله وبركاتــه ،،

الف شكر اخي خالد على الاجابة المفصلة

وهل يوجد مقال تنصح بقرائته ؟

تحياتي

while( "اسلام" )
{
 cout >> "الموت لبني صهيون" >> endl;
}
return "فلسطين";
#7
#include <ctime>
#include <iostream>
using namespace std;

 class EmptyClass { }; 

int main()
{
	clock_t start = clock();
	for (int i = 0; i < 100000; ++i)
		EmptyClass e;

	clock_t duration = clock() - start;
	cout << "stack allocation took " << duration << " clock ticks\n";
	start = clock();
	for ( i = 0; i < 100000; ++i) 
		EmptyClass* e = new EmptyClass;

	duration = clock() - start;
	cout << "heap allocation took " << duration << " clock ticks\n";

return 0;

}
llback.jpg

اشهد ان لا إله إلا الله وان محمدا ً رسول الله

#8

بســم الله الـرحمــن الرحيــم

السلام عليكــم ورحمـة الله وبركاتــه ،،

الف شكر اخي time1 على المثال المرفق

بالفعل يوجد فرق في السرعة فهي في حالة الـ Stack اسرع

تحياتي

while( "اسلام" )
{
 cout >> "الموت لبني صهيون" >> endl;
}
return "فلسطين";
#9

لا أعرف مقالات حول الموضوع :)

تحتاج إلى قليل من الأسمبلي, و قراءة فصل في أحد كتب الـ Data Structures و مقال جيد حول حاسوب von neumann, و ستأخذ فكرة شبه كاملة عن الموضوع :)

يبدو أيضاً أني لم أوضح السؤال جيداً,

انظر إلى كود الأخ time1 .... هل ترى هنا :

for (int i = 0; i < 100000; ++i)
  EmptyClass e;

هل ترى الكائن e.... في كل حلقة يتم إنشاء كائن جديد, و قبل الخروج منها يتم التخلص من ذاكرته و إعادتها إلى نظام التشغيل..... الآن هذا الكائن e يشبه في تصرفه, أي كائن أو متغير عادي معرف داخل أي دالة.... عندما يتم استدعاء الدالة يتم إنشاؤه و قبل الخروج منها يتم إعادة مكانه لنظام التشغيل....

أما في الحالة التالية ..

for ( i = 0; i < 100000; ++i) 
  EmptyClass* e = new EmptyClass;

:

فقمنا بطلب الذاكرة عن طريق new و التي تعني اجحز ذاكرة بحجم الـ Class الذي كتبناه EmptyClass و اجعل اسم ذلك المكان e :)

لا تنسى أن تحرر الذاكرة :angry: :P

الـ Scope هو أول تطور في الـ Programming Style حصل للغات البرمجة :)

إمكانية أن نسحر كل دالة و نوهمها بأنها برنامج جديد :) ثم نقوم بالتحكم في عملية توزيع البيانات بين تلك الدوال. و الخروج بالنتيجة المطلوبة من أول دالة قمنا باستدعائها و التي تسمى لديك main في ++C على سبيل المثال....

عموماً كما قلت لك عشرة ردود لن تكفي, Google صديق الجميع :P

تحياتي,

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 22 مارس 2009 في 18:55

#10

بســم الله الـرحمــن الرحيــم

السلام عليكــم ورحمـة الله وبركاتــه ،،

الف شكر اخي خالد , دائما اجاباتك دقيقة و مفصلة , فبارك الله فيك

... ... ...

انتقلت من VB الى ++C بعد مرور بسيط على الدلفاي وكل ذلك كان من اجل فهم البرمجة

بشكل افضل بعيدا عن المكونات الجاهزة , ولكن يبدو ان الامر يتطلب نظرة واطلاع على بعض

الاسمبلي لفهم الامور بشكل اكبر

قد يبدو ذلك مخالف لمفهوم كثير من المبرمجين الذين يودون دائما الانتقال من الاصعب الى الاسهل

في حين اني كهاوي للبرمجة ولست ممن درسها اكاديميا ارى ان هذا هو الطريق الامثل لفهم البرمجة

لكن حاليا سابقى مع ++C لاني اعمل على مشروع طموح احاول ان اتقن اللغة من خلاله وقد انتقل

بعد ذلك للاسمبلي ان شاء الله تعالى

تحياتي

while( "اسلام" )
{
 cout >> "الموت لبني صهيون" >> endl;
}
return "فلسطين";

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…