PDA

View Full Version : سوال: مشکل بزرگ شدن متغیر string و کاهش سرعت برنامه



saed2006
دوشنبه 30 فروردین 1389, 10:01 صبح
یک متد دارم که شیی از نوع string بر میگردونه
مشکل اینجاس که طول string ممکنه خیلی زیاد بشه و اگه متد بخواد اونو بر گردونه زمان اجرای برنامه خیلی کند میشه
راهی هست که متغیر رو بشکنم ؟
راه بهتری؟

sky_in_iran
دوشنبه 30 فروردین 1389, 10:14 صبح
سلام دوست عزيز
اگه منظورت و درست فهميده باشم هنگام ارسال اطلاعات با حجم بالا فضاي حافظه پرميشه و كندي بوجود مياد درسته ؟ اگه اين باشه شما ميتوني داخل متد اطلاعات و داخل يه فايل تكس بريزي و آدرس و ارسال كني و اونور خوب از فايل بخوني يا اينكه اصلا آدرس ارسال نكي تو محل دريافت يه آدرس ثابت بدي و از اونجا بخوني يا اين كه اطلاعاتت و مثل كار اينترنت كني به صورت بسته بسته ارسال كني كل اطلاعاتتو تقسيم كن به چند بسته و يكي يكي ارسال كن و با هربار ارسال اطلاعات و از حافظه پاك كن و بعد اطلاعات بعدي و ارسال كن فقط اين كارو در Ui انجام نديا برنامت به تعطيلي ميره اين كارو پشن پرده انجام بده در يك ترد ديگه
اميد وارم تونسته باشم كمكت كنم اگه سوال درباره مطالبي كه گفتم داشتيد در خدمتم
موفق باشيد

saed2006
دوشنبه 30 فروردین 1389, 10:19 صبح
سلام دوست عزيز
اگه منظورت و درست فهميده باشم هنگام ارسال اطلاعات با حجم بالا فضاي حافظه پرميشه و كندي بوجود مياد درسته ؟ اگه اين باشه شما ميتوني داخل متد اطلاعات و داخل يه فايل تكس بريزي و آدرس و ارسال كني و اونور خوب از فايل بخوني يا اينكه اصلا آدرس ارسال نكي تو محل دريافت يه آدرس ثابت بدي و از اونجا بخوني يا اين كه اطلاعاتت و مثل كار اينترنت كني به صورت بسته بسته ارسال كني كل اطلاعاتتو تقسيم كن به چند بسته و يكي يكي ارسال كن و با هربار ارسال اطلاعات و از حافظه پاك كن و بعد اطلاعات بعدي و ارسال كن فقط اين كارو در Ui انجام نديا برنامت به تعطيلي ميره اين كارو پشن پرده انجام بده در يك ترد ديگه
اميد وارم تونسته باشم كمكت كنم اگه سوال درباره مطالبي كه گفتم داشتيد در خدمتم
موفق باشيد


str=getStrng()
چجوری بسته بسته بخونم و بریزم توی متغیر

mohammad meta
دوشنبه 30 فروردین 1389, 10:57 صبح
دوست عزیز احتمالا این تاخیر برای زمانی است که این string در حال ایجاد است به خاطر value type بودن
string معمولی اگر شما از کلاس stringBuilder استفاده کنید ممکن مشکلتون رفع بشه .
در مورد ریختن string درون یک فایل فکر نکنم مشکلتون رفع کنه بلکه زمان خواندن نوشتن آن حجم اطلاعات درون یک فایل خودش کلی زمان می گیره 3برابر بلکه بیشتر به علاوه اینکه دوباره باید برای خوانده شدن همان حافظه را لازم دارد.

saed2006
دوشنبه 30 فروردین 1389, 11:30 صبح
دوست عزیز احتمالا این تاخیر برای زمانی است که این string در حال ایجاد است به خاطر value type بودن
string معمولی اگر شما از کلاس stringBuilder استفاده کنید ممکن مشکلتون رفع بشه .
در مورد ریختن string درون یک فایل فکر نکنم مشکلتون رفع کنه بلکه زمان خواندن نوشتن آن حجم اطلاعات درون یک فایل خودش کلی زمان می گیره 3برابر بلکه بیشتر به علاوه اینکه دوباره باید برای خوانده شدن همان حافظه را لازم دارد.

string با stringbuider توی این قصه چه فرقی میکنه؟
حافظه اشغال شده توسط متغیر بزرگ میشه حالا چه string باشه چه strnigbuilder
در مورد فایل اتفاقا جواب میده و سرعت رو افزایش میده
اما ممکنه همیشه نخوایم بریزیم روی فایل اینجا چه باید کرد؟

mohammad meta
دوشنبه 30 فروردین 1389, 12:39 عصر
فرقش اینه که من این احتمال دادم که این کاهش سرعت در برگرداندن string - به دلیل ایجاد string در داخل متد باشه .مثلا شاید اون string داخل حلقه انداخته باشی وقتی شما اطلاعات کامل را نمی دهی انتظار نداشته باش .

اما ممکنه همیشه نخوایم بریزیم روی فایل اینجا چه باید کرد؟
بالاخره یا باید روی هارد ذخیره بشه یا ram معجزه که نمیشه .
در مورد شکستن string شما می توانید string را بوسیله / یا هر چیز دیگه جدا کنی بعد بوسیله string.split()
اون به چند تیکه تقسیم کنید و هرچقدرش را خواستی بفرستی.

علیرضا حسن زاده
دوشنبه 30 فروردین 1389, 13:03 عصر
اگه توجه کنید stringBuilder با String فرق داره فرقشم اینه که اگه بخوای مثلا یه متن رو به صورت کاراکتر به کاراکتر یا کلمه به کلمه پردازش کنی و نتایج اون رو در یه String قرار بدی هرچه قدر متن مورد پردازش طولانی تر باشه سرعت برنامه هم به شدت افت میکنه دلیلش هم اینه که وقتی می خوای یه رشته رو به به یه رشته موجود الحاق کنی در استفاده از کلاس string برای این کار ابتدا یه رشته جدید ایجاد میشه و هر دو رشته در اون ریخته میشه و رشته جدید جایگزین رشته اول میشه ولی در stringBuilder این جوری نیست و باعث افت سرعت پردازشی برنامه نمیشه

حالا اگه اینا که گفتم کارتون رو راه انداخت که هیچ وگرنه یه مطالعه ای در مورد Box و UnBox کردن هم انجام بدین که مشکل برنامه شما به نظر من از همین عمل ناشی میشه و باید کاری بکنی که این عمل اتفاق نیفته.

AliRezaPro
دوشنبه 30 فروردین 1389, 15:50 عصر
چجوری بسته بسته بخونم و بریزم توی متغیر
خروجی رو بصورت ارایه ریترن کن و از آن طرف مقادیر مورد نظرتونو بخونید

sky_in_iran
سه شنبه 31 فروردین 1389, 09:53 صبح
دوستان و اساتيد محترم راههايه گوناگوني و پيشنهاد دادن كه هر كودوم به نوبه خودش قابل مباحثه هستش و راه براي انجام اين كار خيلي زياده به يه راه حل تكيه هيچوقت نكنيد ، درباره سوالم اينجور كه از سوال مطرح بود پردازش آنچناني قرار نيست اتفاق بيفته پس براي انتقال راهايه زيادي هست اگر قراره پردازش بشه پس بهتره يه متد بزاريد براي پردازش و اطلاعات پردازش شده رو كم كم بگيري و در يك جا جم كنيد اينجوري سرعتم بالا ميره اگر پردازش نيست براي انتقال يه متن با حجم بالا پاكت بندي به نظرم بهتره و با سرعت بالاتري تا فايل و string يا stringBuilder . متن و به يك آرايه از بايت تبديل كن بعد در يك آرايه ارسال كن و اگر ميخواي برنامت به مشكل نخوره تو پست قبليمم گفتم برو سراغ پشته پرده يعني ui درگير نشه يعني thread اصلي درگير نشه يعني حافظه رو زياد درگير نكن يه داده ارسال كردي اون بخش از حافظه رو پاك كن يا روهمون رونوشت كنيد به نظر اين راه به صرفه تره

علیرضا حسن زاده
چهارشنبه 01 اردیبهشت 1389, 09:59 صبح
اگر ميخواي برنامت به مشكل نخوره تو پست قبليمم گفتم برو سراغ پشته پرده يعني ui درگير نشه يعني thread اصلي درگير نشه يعني حافظه رو زياد درگير نكن يه داده ارسال كردي اون بخش از حافظه رو پاك كن يا روهمون رونوشت كنيد به نظر اين راه به صرفه تره
این درست که عملیات پردازشی زیاد رو باید در thread انجام بدن ولی همین رونوشت کردن حافظه به نوعی با stringBuilder انجام میشه در ضمن اگه ایشون خودش بخواد حافظه رو پاک کنه و از این قبیل کارها توجه داشته باشین که سربار زیاد و بیهوده ای برای برنامه ایجاد میکنه چون باید به صورت دستی garbage collector رو فراخوانی کنه (با ++C که کار نمی کنیم، مدیریت حافظه باCLR هست).
مشکل اصلی برنامه ایشون هم به نظر من پاس کردن داده بین پشته و حافظه هست (همون Boxing و unboxing) که باید با الگوریتم مناسب تاجایی که می تونن مانع این کاربشن

sky_in_iran
پنج شنبه 02 اردیبهشت 1389, 17:56 عصر
این درست که عملیات پردازشی زیاد رو باید در thread انجام بدن ولی همین رونوشت کردن حافظه به نوعی با stringBuilder انجام میشه در ضمن اگه ایشون خودش بخواد حافظه رو پاک کنه و از این قبیل کارها توجه داشته باشین که سربار زیاد و بیهوده ای برای برنامه ایجاد میکنه چون باید به صورت دستی garbage collector رو فراخوانی کنه (با ++C که کار نمی کنیم، مدیریت حافظه باCLR هست).
مشکل اصلی برنامه ایشون هم به نظر من پاس کردن داده بین پشته و حافظه هست (همون Boxing و unboxing) که باید با الگوریتم مناسب تاجایی که می تونن مانع این کاربشن
دوست عزيز و استاد گرامي براي اين كه سربار زياد رو يه بخش نباشه واسه همين گفتم در يك thread ديگه انجام بده نه اصلي به هرحال هنگام اجرا بخشي از حافظه گرفته ميشه خواه نا خواه پس حالا بايد اون بخش و مديريت كنيم يا بايد حافظه پر و خالي بشه به صورت رونوشت يا اينكه پاك بشه وريخته بشه البته در كدينگ تفاوت زياده اما در هنگام اجرا من تاحال به مشكل سرباري نخوردم اگه شما تجربش و داري بفرما تا مام يه چيزي ياد بگيريم و به اشتباه خودمون پي ببريم و تكراراشتباه نكنيم
خيلي ممنونتون ميشم استاد
موفق باشيد

FastCode
پنج شنبه 02 اردیبهشت 1389, 18:18 عصر
حالا چی توی این string هست؟

hamidsolat
پنج شنبه 02 اردیبهشت 1389, 22:57 عصر
از pionter یا refrence استفاده کن یعنی به جای فرستادن خود متغییر ، آدرس حافظه متغییر برگردون

FastCode
پنج شنبه 02 اردیبهشت 1389, 23:22 عصر
من دارم فکر میکنم که چرا یه نفر باید این همه اطلاعات توی یه string داشته باشه.

hamidsolat
جمعه 03 اردیبهشت 1389, 10:19 صبح
من دارم روی یه برنامه ای کار میکنم که مربوط به پیاده سازی یه مدل زبان فارسی یا حتی پیدا کردن مدل های جدید که لازمه اون کار کردن روی رشته هایی حتی به اندازه یک یا چند مگا بایت حافظه هست

FastCode
جمعه 03 اردیبهشت 1389, 10:33 صبح
چرا از unmanaged memory استفاده نمیکنی؟

char* str = System.Runtime.Interop.Malshal.AllocHGlobal(1<<20);
str[0]='آ';

با unmanaged memory هم سرعت بیشتری به دست میاری و هم قدرت بیشتر برای مدیریت رشته.
در خیلی از موارد هم بر خلاف تصور همه کد شما خواناتر میشه.
فقط یادت نره:Free mallocs.

علیرضا حسن زاده
جمعه 03 اردیبهشت 1389, 12:19 عصر
دوست عزيز و استاد گرامي براي اين كه سربار زياد رو يه بخش نباشه واسه همين گفتم در يك thread ديگه انجام بده نه اصلي به هرحال هنگام اجرا بخشي از حافظه گرفته ميشه خواه نا خواه پس حالا بايد اون بخش و مديريت كنيم يا بايد حافظه پر و خالي بشه به صورت رونوشت يا اينكه پاك بشه وريخته بشه البته در كدينگ تفاوت زياده اما در هنگام اجرا من تاحال به مشكل سرباري نخوردم اگه شما تجربش و داري بفرما تا مام يه چيزي ياد بگيريم و به اشتباه خودمون پي ببريم و تكراراشتباه نكنيم
خيلي ممنونتون ميشم استاد
موفق باشيد
اگه به مشکل سربار اضافی برنامه بر نخوردین ممکنه حجم عملیات کم بوده ولی تو برنامه ای که من نوشتم یه رشته معمولا دارای 5000 در حداقل و سایر موارد بیشتر کلمه داشت و کاراکترهای این کلمات هم باید به صورت تک به تک و با توجه به حروف ماقبل و بعد از خودش عملیاتی صورت می گرفت که در این حالت بالطبع بعد از انجام عملیات باید کاراکتر و در حالت کلی کلمه در که تغییر پیدا کرده در یه جای دیگه ذخیره بشه. حالا شما یه همچین کاری رو با کلاس String و StringBuilder انجام بده (در کد نویسی زیاد تفاوتی نمیبینی) سرعت انجام عملیات رو مقایسه کن واسه برنامه من که خیلی جالب بود و سرعت رو خیلی بالا برد (اینم توجه داشته باشید که چه در یم Thread دیگه انجام بشه و همون Thread حجم عملیاتی که انجام میشه هیچ تفاوتی نمیکنه فقط در مدت پردازش GUI برنامه هنگ نمیکنه)
روشی رو هم که دوست عزیز FastCode گفتن تقریبا همین روشی هست که بنده گفتم ولی با روش Unmanage :چشمک: