मैं आपके परिणामों को एक समान आकार के एमएस एसक्यूएल सर्वर डेटासेट के साथ एक AdoQuery का उपयोग कर पुन: पेश कर सकता हूं।
हालांकि, कुछ लाइन-प्रोफाइलिंग करने के बाद, मुझे लगता है कि मुझे इसका जवाब मिल गया है, और यह थोड़ा सा अंतर्ज्ञानी है। मुझे यकीन है कि डेल्फी में डीबी प्रोग्रामिंग का उपयोग इस विचार के लिए किया जाता है कि डेटासेट के माध्यम से लूपिंग बहुत तेज हो जाती है यदि आप अक्षम/सक्षम नियंत्रणों पर कॉल द्वारा लूप को घेरते हैं। लेकिन डेटासेट से जुड़े डीबी-जागरूक नियंत्रण नहीं होने पर कौन ऐसा करने के लिए परेशान होगा?
ठीक है, यह पता चला है कि आपकी स्थिति में, भले ही कोई डीबी-जागरूक नियंत्रण न हो, फिर भी यदि आप अक्षम/सक्षम नियंत्रणों का उपयोग करते हैं तो गति बहुत बढ़ जाती है।
if ControlsDisabled then
RecordNumber := -2 else
RecordNumber := Recordset.AbsolutePosition;
और मेरी लाइन प्रोफाइलर के अनुसार, जबकि AdoQuery1.Next पाश नहीं AdoQuery1.Eof अपने समय से 98.8% को क्रियान्वित करने में खर्च करता है:
कारण AdoDB.Pas में TCustomADODataSet.InternalGetRecord इस होता है वह यह है कि काम
RecordNumber := Recordset.AbsolutePosition;
! Recordset.AbsolutePosition की गणना, निश्चित रूप से, रिकॉर्ड्स इंटरफ़ेस के "गलत पक्ष" पर छिपी हुई है, लेकिन तथ्य यह है कि इसे कॉल करने का समय स्पष्ट रूप से आगे बढ़ता है जब आप रिकॉर्डसेट में जाते हैं तो यह अनुमान लगाता है कि इसकी गणना की गई है रिकॉर्डसेट के डेटा की शुरुआत से गिनती करके।
बेशक, ControlsDisabled
को कॉल किया गया है और EnableControls
पर कॉल द्वारा पूर्ववत नहीं किया गया है। तो, अक्षम/सक्षम नियंत्रण से घिरे लूप के साथ पुनः प्रयास करें और उम्मीद है कि आपको मेरा एक ही परिणाम मिल जाएगा। ऐसा लगता है कि आप सही थे कि मंदी स्मृति आवंटन से संबंधित नहीं है।
निम्नलिखित कोड का उपयोग करना:
procedure TForm1.btnLoopClick(Sender: TObject);
var
I: Integer;
T: Integer;
Step : Integer;
begin
Memo1.Lines.BeginUpdate;
I := 0;
Step := 4000;
if cbDisableControls.Checked then
AdoQuery1.DisableControls;
T := GetTickCount;
{.$define UseRecordSet}
{$ifdef UseRecordSet}
while not AdoQuery1.Recordset.Eof do begin
AdoQuery1.Recordset.MoveNext;
Inc(I);
if I mod Step = 0 then begin
T := GetTickCount - T;
Memo1.Lines.Add(IntToStr(I) + ':' + IntToStr(T));
T := GetTickCount;
end;
end;
{$else}
while not AdoQuery1.Eof do begin
AdoQuery1.Next;
Inc(I);
if I mod Step = 0 then begin
T := GetTickCount - T;
Memo1.Lines.Add(IntToStr(I) + ':' + IntToStr(T));
T := GetTickCount;
end;
end;
{$endif}
if cbDisableControls.Checked then
AdoQuery1.EnableControls;
Memo1.Lines.EndUpdate;
end;
निम्न परिणाम (DisableControls साथ अपवाद का उल्लेख नहीं बुलाया नहीं) मैं हो:
Using CursorLocation = clUseClient
AdoQuery.Next AdoQuery.RecordSet AdoQuery.Next
.MoveNext + DisableControls
4000:157 4000:16 4000:15
8000:453 8000:16 8000:15
12000:687 12000:0 12000:32
16000:969 16000:15 16000:31
20000:1250 20000:16 20000:31
24000:1500 24000:0 24000:16
28000:1703 28000:15 28000:31
32000:1891 32000:16 32000:31
36000:2187 36000:16 36000:16
40000:2438 40000:0 40000:15
44000:2703 44000:15 44000:31
48000:3203 48000:16 48000:32
=======================================
Using CursorLocation = clUseServer
AdoQuery.Next AdoQuery.RecordSet AdoQuery.Next
.MoveNext + DisableControls
4000:1031 4000:454 4000:563
8000:1016 8000:468 8000:562
12000:1047 12000:469 12000:500
16000:1234 16000:484 16000:532
20000:1047 20000:454 20000:546
24000:1063 24000:484 24000:547
28000:984 28000:531 28000:563
32000:906 32000:485 32000:500
36000:1016 36000:531 36000:578
40000:1000 40000:547 40000:500
44000:968 44000:406 44000:562
48000:1016 48000:375 48000:547
MDAC/ADO परत में सीधे AdoQuery1.Recordset.MoveNext
कॉल कॉलिंग , पाठ्यक्रम, जबकि AdoQuery1.Next मानक TDataSet मॉडल के सभी ओवरहेड शामिल है। सर्ज क्राइकोव ने कहा, कर्सरोकोकेशन को बदलना निश्चित रूप से एक फर्क पड़ता है और हमने जो मंदी देखी है, वह प्रदर्शित नहीं करती है, हालांकि स्पष्ट रूप से यह क्लाउसे क्लाइंट का उपयोग करने और अक्षम कॉन्ट्रोल को कॉल करने से काफी धीमी है। मुझे लगता है कि यह वास्तव में निर्भर करता है कि आप क्या करने की कोशिश कर रहे हैं कि क्या आप RecordSet.MoveNext के साथ clUseClient का उपयोग करने की अतिरिक्त गति का लाभ उठा सकते हैं।
नहीं। मैं प्रोग्रामेटिक रूप से नियंत्रण बना रहा हूं, नमूना कोड में आप जो देख सकते हैं उससे कहीं ज्यादा कुछ नहीं है। – saastn
क्या आपके लिए लूप बंद नहीं है? वैसे भी, क्या आप हैरान हैं कि यदि आप बहुत सारे रिकॉर्ड पढ़ते हैं, तो इसमें बहुत सारी मेमोरी आवंटन शामिल है, और इन्हें अधिक स्मृति आवंटित करने में अधिक समय लगता है? – MartynA
@ मार्टिनए आप लूप के बारे में सही हैं। लेकिन मैं यह नहीं कह सकता कि यह स्मृति आवंटन है जो इसे धीमा कर देता है। ऐसा लगता है कि यह 'टेबल' ओपन 'में सभी रिकॉर्ड्स प्राप्त करता है, टास्क मैनेजर उस लाइन को चलाने के बाद कोई मेमोरी आवंटन नहीं दिखाता है। – saastn