PDA

View Full Version : سرعت بسیار کند سی شارپ در مقایسه با دلفی



esmit61
جمعه 30 خرداد 1393, 21:31 عصر
سلام. من قطعه کد زیر رو با C#‎‎‎‎‎ نوشتم. زمان اجراش روی کامپیوتر من حدود 80 ثانیه هست.
ولی وقتی معادل همین کد رو با دلفی اجرا میکنم حدود 10 ثانیه زمان میبره.(توی دلفی از AdoConnection استفاده میکنم)
احساس میکنم یه جای کارم اشکال داره. ممنون میشم راهنمایی کنید
البته من این سوال رو توی بخش سی شارپ هم پرسیدم.
SqlConnection conn = new SqlConnection("Data Source=(local);Initial Catalog=Test;Integrated Security=SSPI");
conn.Open();
Random rnd = new Random();
string squery="123";
SqlCommand sc = new SqlCommand(squery, conn);
Stopwatch sw = Stopwatch.StartNew();
string s = string.Empty;
progressBar1.Maximum = 10000;
for (int i = 0; i < 10000; i++)
{
for (int j = 0; j < 5; j++)
{
byte ch = (byte)rnd.Next(65, 91);
s = s + ch.ToString();
}
squery = "Insert into t1 values('"+s+"')";
sc.CommandText = squery;
sc.ExecuteNonQuery();
++progressBar1.Value;
s = string.Empty;
}
sw.Stop();
long Duration= sw.ElapsedTicks;
MessageBox.Show(Duration.ToString());



این هم کد دلفی:


startTime:= GetTickCount;
ProgressBar1.Max:= 10000;
for i := 0 to 10000 do begin
s:='';
for j:=0 to 5 do begin
ch:= RandomRange(65,91);
s:=s+IntToStr(ch);
end;
ADOQuery1.SQL.Text:='Insert into t1 values('+QuotedStr(s)+')';
ADOQuery1.ExecSQL;
ProgressBar1.Position:= ProgressBar1.Position+1;
end;
endTime:= GetTickCount;
ShowMessage(IntToStr(endTime-startTime));

یوسف زالی
جمعه 30 خرداد 1393, 22:33 عصر
سلام.
کد رو بدون progress bar دوباره تست کنید و مقایسه کنید.

BORHAN TEC
شنبه 31 خرداد 1393, 10:41 صبح
با سلام،
در مورد سوال شما توجه به نکات زیر مفید خواهد بود:

1- در کد C#‎‎‎‎‎‎‎‎‎ متغیر ch رو در بیرون از حلقه تعریف کنید.

2- در هر دو کد برنامه رو به صورت Run Without Debugging اجرا کنید.

3- همانطور که یوسف گفت استفاده از ProgressBar رو نادیده بگیرید.

4- این دو کد معادل یکدیگر نیستند. تعداد تکرارها در کد دلفی شما بیشتر است. زیرا در حلقه دلفی از کوچکتر مساوی استفاده شده و در کد سی شارپ از کوچتر استفاده شده. به عبارتی برای معادل شدن کدها باید در کد دلفی حد بالای حلقه اول را 9999 و در حلقه داخلی 4 قرار دهید.

5- در کد سی شارپ متغیر های حلقه را در بیرون از حلقه تعریف کنید(منظور متغیرهای i و j هست). البته این مورد رو در مورد C#‎‎‎‎‎‎‎‎‎ تست نکردم ولی یادمه که در زبان Oxygene این مورد تاثیر زیادی داشت.

6- به این نکته توجه داشته باشید که اختلاف سرعت بین Delphi و C#‎‎‎‎‎‎‎‎‎ تا حد زیادی طبیعی است. چرا که C#‎‎‎‎‎‎‎‎‎ زبانی است که تحت VM اجرا می شود ولی Delphi اینگونه نیست و از لحاظ اجرا برنامه های ساخته شده با دلفی به سخت افزار نزدیکتر هستند.

7- این موردی که شما گفتید تا حد زیادی می تواند به نحوه پیاده سازی فریم ورک کار با پایگاه داده هم مربوط باشد. به عنوان مثال اگر در سمت دلفی به جای ADO از FireDAC استفاده کنید بدون شک سرعت بسیار بالاتر از این خواهد بود.

8- همچنین احتمال دارد که شرایط تست کاملاً یکسان نباشد. مثلاً ممکن است که در مورد C#‎‎‎‎‎‎‎ از جدولی استفاده کرده باشید که دارای ایندکس هست ولی در مورد دلفی از جدولی استفاده کرده باشید که ایندکس ندارد. توجه به این نکته ضروری است که ایندکسها سرعت درج اطلاعات را پایین می آورند ولی سرعت خواندن داده های مورد نظر را بالا می برند.

9- گذشته از مقایسه سرعت دلفی و سی شارپ اگر هدف شما افزایش سرعت است باید از Array DML استفاده کنید. به این معنی که درج تمامی اطلاعات یکباره صورت بگیرد و نه تک تک. این مورد در مواقعی مفید است که شما می خواهید داده های زیادی را به یکباره در پایگاه داده درج کنید، از مزایای دیگر این مورد این است که در محیطهای تحت شبکه، استفاده از این تکنیک ترافیک را به نحو چشمگیری پایین می آورد.

موفق باشید...

esmit61
شنبه 31 خرداد 1393, 13:25 عصر
دوستان عزیز. اشکال فقط از عملیات I/O هست. کارهایی که گفتید انجام شد. تاثیری نداشت.
من تازه دارم مهاجرت میکنم به سی شارپ. یعنی واقعاً کار سی شارپ با پایگاه داده اینقدر کنده ؟(که البته بعید میدونم اینجوری باشه).
به احتمال زیاد یه تنظیمی رو دارم بد انجام میدم
باز هم منتظر راهنماییهاتون هستم

Arman_1367
پنج شنبه 30 مرداد 1393, 22:53 عصر
دوست عزیز خیلی جالب هست که قبل از مهاجرت سعی می کنید تست بکنید و جواب درست رو به دست بیارید و بهتون پیشنهاد می کنم حتماً همین راه رو ادامه بده تا بعداً دچار مشکل نشید.
تو سی شارپ روش پیاده سازی windowsform خیلی متفاوت هست و کلا نسبت به vcl سرعت پایین تری می تونی ازش بگیری دوستانی که فرموده بودند از progressbar صرف نظر کن نظر کاملا درستی داشتند.درباره casting هم همین مسئله مطرح میشه و بهتره بدونی که یکی از چیزهایی که در سرعت اجرای برنامه های تحت دات نت مهم هست همین تبدیل انواعه که در دلفی خیلی باهاش روبرو نمی شی می تونی از این لینک ها استفاده کنی : لینک 1 (http://www.codeproject.com/Articles/8052/Type-casting-impact-over-execution-performance-in) و لینک 2 (http://blog.goyello.com/2013/01/07/8-most-common-mistakes-c-developers-make/) و لینک 3 (http://www.techgalaxy.net/Docs/Dev/5ways.htm) و اما یک نکته دیگه که هست به جای استفاده از + برای ساختن query از string.format استفاده کن و یک چیز دیگه هم هست اونم اینه که تو حلقه ارتباطت رو با بانک قطع کنید و دوباره وصل کنید برای درج، برنامه ها رو تو شبکه اجرا کنید و نتیجه رو ببینید تا با ویژگی سی شارپ و ADO.net آشنا بشید. البته نکاتی که دوستان فرمودند رو هم فراموش نکنید.