PDA

View Full Version : سوال: تفاوت بین List و ArrayList در تخصیص حافظه



alireza_tavakol
چهارشنبه 07 مرداد 1388, 19:56 عصر
دو نوع ساختمان داده ها برای ذخیره اطلاعات مربوط به هم در سی شارپ وجود دارد ( List و ArrayList ) می خواستم بدونم اگه دو تا متغییر به شکل زیر تعریف بشه از نظر فنی چه تفاوتی بین این دو متغییر وجود داره ؟


List<Object> a = new List<Object>();

ArrayList b = new ArrayList();

با تشکر

Mahdi.Kiani
چهارشنبه 07 مرداد 1388, 22:50 عصر
لیست های ژنریک مزایای زیادی نسبت به ArrayList دارند./
یکی از این مزایا جلوگیری از عملیات Boxing و unBoxing می باشد که هنگام استفاده از ArrayList ها بوجود می آید که باعث کاهش کارایی برنامه میشود
مزیت دیگر آن نسبت به ArrayList ها Type Safe بودن آن یا همان Strongly Typed بودن آن ها می باشد. بعنوان مثال زمانی که شما لیست ژنریکی از int ها تولید می کنید، تنها می توانید مقادیری از نوع int به لیست وارد کنید. این موضوع در زمان کمپایل چک می گردد و از بروز خطاهای runtime جلوگیری می کند./
....
یادمه خیلی وقت پیش در این زمینه با مثال کامل در یکی از پست ها توضیح دادم. جستجو کنید پیدا می کنید.
موفق باشید

alireza_tavakol
پنج شنبه 08 مرداد 1388, 00:07 صبح
ببخشید ولی این توضیحاتی که مبذول فرمودید مربوط میشه به تفاوت های کلی بین لیست های جنریک با arrylist ، ولی من می خواستم بدونم از نظر تخصیص حافظه بین این دو متغییر تعریف شده تفاوتی هست یا نه ؟:متفکر:( دقیقا این موضوع در عنوان تاپیک قید شده )
همان طوری که می دونید اعضای کلاس list با اعضای کلاس arrylist متفاوت است ولی منظور من از تفاوت فقط تخصیص حافظه است و کاری با وجوه تمایز دیگه ندارم.
توضیح اضافه من در هنگام تعریف لیست جنریک نوع لیست را object قرار دادم یعنی مثل حالتی که arrylist داره حالا عرض بنده حقیر اینکه آیا فرقی بین متغییر a و b وجود داره؟

با تشکر از توجه شما دوست گرامی

hamedmehdihamed
شنبه 10 مرداد 1388, 04:05 صبح
در list مقدار حافظه ای که تخصیص داده می شود ثابت است یعنی چه شما از این متغیر استفاده کنید یا نکنید حافظه ی استفاده شده ثابت است، اما در arraylist مقدار حافظه ی اشغال شده پویا است ، یعنی به میزانی که از متغیرتون استفاده می کنید حافظه اسغال می شود، در ضمن در arraylist اگر خانه ای را هم حذف کنید،مقدار حافظه متناسب با آن به حافظه برگردانده می شود و به طور فیزیکی هم حذف میگردد اما در list شما نمیتونید خانه ای را به طور فیزیکی حذف کنید.
به عبارت دیگه
list:میزان حافظه ی تخصیص داده شده ایستاست
arraylist:میزان حافظه ی تخصیص داده شده پویاست
این چزیه که من میدونم شاید.............:لبخندساده:

alireza_tavakol
شنبه 10 مرداد 1388, 09:40 صبح
در list مقدار حافظه ای که تخصیص داده می شود ثابت است
1- اگه شما میفرمایید حافظه ای که به list اختصاص پیدا میکنه از نوع ایستا است پس نباید list که من تعریف کردم امکان رشد داشته باشه ، در صورتی که توسط متد add می توان به اعضای لیست عضو جدید اضافه کرد

2- اگه شما می فرمایید که حافظه ثابت است پس در هنگام تعریف کردن لیست باید از من به اجبار پرسیده شود که : توی برنامه نویس که می خوای لیست ثابتی داشته باشی تعیین که اندازه size لیست در حافظه به چه میزان باشه ، در صورتی که در هنگام تعریف لیست همچین پارامتری در سازنده کلاس یا و جود نداره یا اجباری نیست

با تشکر از پاسخ شما

mehdi.mousavi
شنبه 10 مرداد 1388, 10:00 صبح
دو نوع ساختمان داده ها برای ذخیره اطلاعات مربوط به هم در سی شارپ وجود دارد ( List و ArrayList ) می خواستم بدونم اگه دو تا متغییر به شکل زیر تعریف بشه از نظر فنی چه تفاوتی بین این دو متغییر وجود داره ؟

سلام.
پاسخ دادن به این سوال یه خرده دشواره، چرا که ممکنه این دو کلاس از دو Growth Algorithm متفاوت استفاده کنن. ممکنه برای تعداد X عنصر، یکی از دیگری بهتر عمل کنه، اما برای X + 1 قضیه کاملا برعکس باشه. برای همین، فکر میکنم باید کد IL تولید شده توسط این دو کلاس رو بررسی کرد تا به پاسخ رسید. اما آیا واقعا نگهداری Object (جای نمونه اصلی کلاس) ضرورتی داره؟

alireza_tavakol
شنبه 10 مرداد 1388, 13:54 عصر
اما آیا واقعا نگهداری Object (جای نمونه اصلی کلاس) ضرورتی داره؟

بله ضرورت داره ! ( با یک مثال کاملا" انتضایی ضرورت مسئله رو شرح میدم )

من یک برنامه Tier 3 دارم . در پایگاه داده های برنامه من جدولی برای ذخیره اطلاعات پرسنلی کارمندان در نظر گرفته شده . این جدول 50 فیلد داره و هر فیلد قرار است داده های بسیار حجیمی را در خود ذخیره نمایید .

من در لایه UI اطلاعات پرسنلی کارمندی که قرار است استخدام شود رو دریافت میکنم و اطلاعات در یافت شده از کاربر را به لایه BLL ارسال می نمایم تا در جدول مربوطه ذخیره شود . ولی مشکل در هنگام ارسال اطلاعات است به شکلی که اگه قرار باشه به اعضای هر پارامتر متغییر جداگانه ای در نظر گرفته شود ، باید در هنگام صدا زدن متد add کلاس کارمند 50 پارامتر ارسال شود ، این عمل باعث کاهش خوانایی کلاس مربوطه میشود . پس باید چاره ای اندیشید ، در همچین مواقعی از ساختمان داده های structs استفاده میشود ولی مشکلی که مطرح میشود این است که ساختمان structs از نوع حافظه های value types می باشد و برای ذخیره شده این نوع ساختمان ها از حافظه stack استفاده می شود و باعث کاهش performance در اجرای برنامه می شود چون حداکثر حجم stack برابر است با 64KB ولی داده های من حجیم می باشد. پس به صلاح است که از ساختمان دیگری برای ذخیره سازی اطلاعات استفاده کرد که هم در حافظه heap ذخیره شود و هم بتوان انواع مختلف داده را در کنار هم نگه داری کرد ، پس دو راه برای من بیشتر نمی ماند
1- استفاده از list با نوع Object
2- استفاده از ArrayList
حال سوال مطرح میشود که کدام یک از این دو نوع ساختمان داده بهیه تر میباشد و در کدام جایگاه ها نسبت به هم یکسان عمل می کنند و در کدام جایگاه متفاوت هستند

mehdi.mousavi
شنبه 10 مرداد 1388, 15:01 عصر
بله ضرورت داره ! ( با یک مثال کاملا" انتضایی ضرورت مسئله رو شرح میدم )

من یک برنامه Tier 3 دارم . در پایگاه داده های برنامه من جدولی برای ذخیره اطلاعات پرسنلی کارمندان در نظر گرفته شده . این جدول 50 فیلد داره و هر فیلد قرار است داده های بسیار حجیمی را در خود ذخیره نمایید .

من در لایه UI اطلاعات پرسنلی کارمندی که قرار است استخدام شود رو دریافت میکنم و اطلاعات در یافت شده از کاربر را به لایه BLL ارسال می نمایم تا در جدول مربوطه ذخیره شود . ولی مشکل در هنگام ارسال اطلاعات است به شکلی که اگه قرار باشه به اعضای هر پارامتر متغییر جداگانه ای در نظر گرفته شود ، باید در هنگام صدا زدن متد add کلاس کارمند 50 پارامتر ارسال شود ، این عمل باعث کاهش خوانایی کلاس مربوطه میشود . پس باید چاره ای اندیشید ، در همچین مواقعی از ساختمان داده های structs استفاده میشود ولی مشکلی که مطرح میشود این است که ساختمان structs از نوع حافظه های value types می باشد و برای ذخیره شده این نوع ساختمان ها از حافظه stack استفاده می شود و باعث کاهش performance در اجرای برنامه می شود چون حداکثر حجم stack برابر است با 64KB ولی داده های من حجیم می باشد. پس به صلاح است که از ساختمان دیگری برای ذخیره سازی اطلاعات استفاده کرد که هم در حافظه heap ذخیره شود و هم بتوان انواع مختلف داده را در کنار هم نگه داری کرد ، پس دو راه برای من بیشتر نمی ماند
1- استفاده از list با نوع Object
2- استفاده از ArrayList
حال سوال مطرح میشود که کدام یک از این دو نوع ساختمان داده بهیه تر میباشد و در کدام جایگاه ها نسبت به هم یکسان عمل می کنند و در کدام جایگاه متفاوت هستند

سلام.
من متوجه نشدم، خیلی پیچیده بود.


اطلاعات دریافتی از کاربر، به Middle Tier میره. BLO جایی هستش که Schema یک کارمند، ارتباط یک کارمند با فلان بخش و ... تعیین میشه. در اینجا شما Entity های Employee، Office و ... رو تعریف می کنید و روابط بین این Entity ها رو بصورت Object Oriented نشون می دید. حالا ممکنه کارمند، 5 تا Property داشته باشه، ممکنه 50 تا داشته باشه. اهمیتی نداره.
کلاس کارمند، برای چی Add داره؟ شما باید Collection ای از کارمند ها داشته باشید که هر کارمند، هنگام ایجاد به این Collection افزوده بشه. این Collection ای از کارمند ها هستش که باید Add داشته باشه.
دلیلتون رو برای استفاده از struct متوجه نشدم. Employee و Office و ... هر کدوم یک کلاس هستن که Property هایی مثل Age، Name و ... دارن. شما مگه Employee رو یک Structure تعریف کردید؟

نگاه کنید:

Employee emp = new Employee();
emp.Age = 12;
emp.Name = "qweqwe";
//assign whatever property you would like...

FacadeLayer.AddNewEmployee(emp);

اینجا من یه Employee میسازم، Property هاشو set میکنم (هر چند تا که می خواد باشه)، بعدش به لایه خارجی (Facade Layer) میگم که اینو اضافه کنه با بانک. لایه خارجی بنوبه خودش، بلده چطور با DALc کار کنه، کار رو باید Transactional انجام بده یا خیر و ... در برخی موارد، ممکنه بخواهید 10 تا Employee رو با هم AddNew کنید. در چنین شرایطی لایه خارجی شما، متود AddNewEmployee رو Overload کرده و یه Collection ای از Employee ها رو هم قبول می کنه... باز هم اینجا اون میدونه که چطوری با DALc کار کنه و عمل Insert رو انجام بده. Employee هم یک کلاسه که در BLL تعریف شده و روابطش (همونطور که گفتم) با بقیه Entity ها مشخصه...

میشه دقیقتر توضیح بدید که چی کار کردید؟

alireza_tavakol
شنبه 10 مرداد 1388, 16:05 عصر
سلام. من با یک مثال فرضی می خواستم منظورم رو منتقل کنم ولی متاسفانه مثالی که مطرح کردم خیلی خوب نبود و تازه قضیه بحرانی تر شد

از اول میگم

من قرار یکسری داده با انواع متفاوت( int , float , string , ... ) رو در کنار هم ذخیره کنم
من سه راه برای ذخیره کردن داده های متفاوت در کنار هم رو بلدم

1- استفاده از structs
2- استفاده از list های عمومی ( البته با نوع object ، چون نوعی هر داده ای که قرار است در هر سلول قرار گیرد متفاوت است )
3- استفاده از ArrayList

حالا مشکل من اینکه محاسن و معایب راه دوم رو نسبت به راه سوم نمی دونم
به عبارت دیگه نمی دونم از روش دوم به مطلوب خودم برسم بهتر یا از روش سوم ، به نتیجه بهتری می رسم

امید وارم واضح گفته باشم

mehdi.mousavi
شنبه 10 مرداد 1388, 16:37 عصر
من قرار یکسری داده با انواع متفاوت( int , float , string , ... ) رو در کنار هم ذخیره کنم امید وارم واضح گفته باشم

سلام.
بله، واضح گفتید. میشه دقیق بگید این اطلاعات چی هستن؟ (اینطوری شاید بشه راه حل مناسبی ارائه داد). آیا ممکنه یک تایپ دو بار تکرار بشه؟ و اگر تکرار بشه، شما از کجا می تونید این دو رو از هم تمیز بدید؟ فرض کنیم یکی نرخ دلار رو نشون میده و دیگری وزن یک آیتم رو. در واقع Schema این داده ها چی هستش؟ (متوجه منظورم میشید؟)

برای همین میگم اصل مطلب رو بگید تا بگم چی کار کنید.

Mahdi.Kiani
شنبه 10 مرداد 1388, 19:31 عصر
سلام
ببینید زمانی که شما می خواهید اطلاعات کارمندی را ثبت کنید،رش استاندارد به این شکل است که یک نمونه از entity مربوط به کارمند ایجاد می کنید، خواص این نمونه را با اطلاعاتی که از کاربر دریافت می کنید پر می کنید و در نهایت این نمونه را به لایه های مربوطه پاس می دهید تا در نهایت اطلاعات ذخیره گردنند.
در متدی که عملیات ذخیره کردن را انجام میده بسته به نوع روشی که شما استفاده کرده باشید،می توانید اطلاعاتی که تحت عنوان یک نمونه از entity مربوط به کارمند از لایه UI آمده است را استخراج کنید و آن ها را به متد های مربوطه که در نهایت به پروسیجرهای دیتابیس متصل می شوند پاس دهید./
نیازی نیست که شما متدی داشته باشید که 50 ورودی داشته باشه. البته می توانید overload هایی بسته به نیازتون برای متد های Add و .. داشته باشید./
***********
شاید هنوز هم متوجه منظور شما و چیزی که نیاز دارید نشدم./در این صورت مثالتان را به واقعیت نزدیکتر کنید./

alireza_tavakol
شنبه 10 مرداد 1388, 20:46 عصر
سلام و عرض ارادت خدمت دوستان

در عکس ضمیمه شده این پست خروجی برنامه ای است برای به نمایش کشیدن فضای حالت بازی 8-Puzzle

http://www.uui.ir/show-image.php?id=aa8e203e35fc4f6d6b42222c7874fcee

همان گونه که در شکل مشخص شده کاربر مقداری را به عنوان مقدار اولیه و نیز مقداری را به عنوان نتیجه نهایی وارد می نماید

برنامه من قرار است گراف حالت های مختلف را ترسیم نمایید تا سرانجام به نتیجه نهایی کاربر برسد

بعضی از حالت های ایجاد شده بلا استفاده است و در رسیدن به جواب نقشی ندارد و بعضی از حالات در رسیدن به جواب تاثیر گذار می باشد

برنامه من وقتی به جواب نهایی رسید مسیر رسیدن به جواب را با رنگ قرمز مشخص می نماید

لازم است هر گره ای که تولید میشود بداند که پدرش کیست و چند فرزند تولید شده دارد و چند فرزند تولید نشده داره همچنین بداند قادر نیست چه فرزندی داشته باشد ( فرزند تکراری)
لازم است هر گره بداند خودش در رسیدن به جواب تاثیر گذار است یا نه ( البته در هنگام تولید گره این فیلد بلا مقدار است تا پایان برنامه )
لازم است هر گره بداند در چه سطحی از گراف قرار دارد
لازم است هر گره بداند از سمت چپ در هنگام ترسیم چندمین گره است
لازم است هر گره محاسباتی از قبیل مشخص شده location خودش را در هنگام ترسیم انجام دهد
و ...

حالا من از شما می پرسم Schema این گره ها را چگونه متصور شوم که اصولی باشد

من این برنامه را نوشته ام ولی تعداد گره ها که از 50000 بیشتر می شود سرعت انجام عملیات به شدت افت میکند

با تشکر از دوستان

Mahdi.Kiani
شنبه 10 مرداد 1388, 22:37 عصر
این سوال چه ربطی به سه لایه و کارمندا ن و کلا بحث این تاپیک داره؟

alireza_tavakol
یک شنبه 11 مرداد 1388, 01:06 صبح
برای همین میگم اصل مطلب رو بگید تا بگم چی کار کنید.

اصل مطلب اینکه من برای نگهداری اطلاعات که در هر کدام از گره های این گراف لازم است باید انواع مختلف داده ها در کنار هم ذخیره شود


من سه راه برای ذخیره کردن داده های متفاوت در کنار هم رو بلدم

1- استفاده از structs
2- استفاده از list های عمومی ( البته با نوع object ، چون نوعی هر داده ای که قرار است در هر سلول قرار گیرد متفاوت است )
3- استفاده از ArrayList

حالا مشکل من اینکه محاسن و معایب راه دوم رو نسبت به راه سوم نمی دونم
به عبارت دیگه نمی دونم از روش دوم به مطلوب خودم برسم بهتر یا از روش سوم ، به نتیجه بهتری می رسم

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


می خواستم بدونم از نظر تخصیص حافظه بین این دو متغییر تعریف شده تفاوتی هست یا تفاوتی وجود ندارد ؟

List<Object> a = new List<Object>();

ArrayList b = new ArrayList();


اون مثال کارمند رو هم فرضی مطرح کردم چون ترسیدم که اگه در رابطه با برنامه 8 puzlle بخوام توضیح بدم ، هم قضیه خیلی پیچیده میشه و هم ربطی با موضوع تاپیک نداره :ناراحت:

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

کلا" اگه دوستان اسرار نمیکردن اصل قضیه رو شرح بدم کار به اینجا نمیکشد که مطالبی که ربطی با عنوان تاپیک ندارد مطرح گردد ( ببخشید :خجالت: )

mehdi.mousavi
یک شنبه 11 مرداد 1388, 10:09 صبح
سلام و عرض ارادت خدمت دوستان در عکس ضمیمه شده این پست خروجی برنامه ای است برای به نمایش کشیدن فضای حالت بازی 8-Puzzle همان گونه که در شکل مشخص شده کاربر مقداری را به عنوان مقدار اولیه و نیز مقداری را به عنوان نتیجه نهایی وارد می نماید برنامه من قرار است گراف حالت های مختلف را ترسیم نمایید تا سرانجام به نتیجه نهایی کاربر برسد

من این برنامه را نوشته ام ولی تعداد گره ها که از 50000 بیشتر می شود سرعت انجام عملیات به شدت افت میکند با تشکر از دوستان

سلام.
راستش من یکه خوردم وقتی اینو دیدم. میشه توضیح بدید که حل این مساله چه ربطی به نگهداری یه List ای از Object ها داره؟ این یه درخته، با node های مشخص. هر node هم یه سری خصیصه داره و ... برای حل این مساله، میشه از الگوریتم A* یا روشهای Heuristics و ... استفاده کرد. اما در هیچیک از اینها، نیازی به نگهداری یک لیستی از Object ها نخواهید داشت. به نظرم، دوباره مساله رو برای خودتون تحلیل کنید و راه حل مناسبی برای حل مساله انتخاب کنید. (اگر نمیخواهید از روشهای شناخته شده استفاده کنید). در هر حال، این لینک ها شاید بدردتون بخوره:




A* Algorithm
(http://en.wikipedia.org/wiki/A*_search_algorithm)
8 Puzzle Code Example Share (http://8-puzzle.blogspot.com/)
The 8 Puzzle (http://www.permadi.com/java/puzzle8/)



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

alireza_tavakol
یک شنبه 11 مرداد 1388, 11:33 صبح
ببخشید میشه بفرمایید من اطلاعات متفاوتی که در هر گره وجود داره رو باید توسط کدام نوع داده یا ساختمان ذخیره کنم؟

mehdi.mousavi
یک شنبه 11 مرداد 1388, 12:30 عصر
ببخشید میشه بفرمایید من اطلاعات متفاوتی که در هر گره وجود داره رو باید توسط کدام نوع داده یا ساختمان ذخیره کنم؟

من پاسختون رو به دقت در پست قبلی دادم. این، یک درخت هست، حاوی N تا node.
Node کلاسی هستش که هر یک از گره ها رو نشون میده و در درون خودش، علاوه بر node پدر و فرزندان، حاوی اطلاعاتی هستش که شما دوست دارید در مورد هر node داشته باشید...
حتی در یکی از سه لینکی که در پست قبل بهتون دادم، پیاده سازی این الگوریتم نشون داده شده (به زبان C++) و گمان نمیکنم که دیگه چیز مجهولی در مورد این مساله وجود داشته باشه.

موفق باشید.