سؤال

لدي قائمة Stringlist تحتوي على 10000 إدخال.لدي روتين عشوائي، ولكن الوصول إلى أي من العناصر يستغرق الكثير من الوقت.يستغرق الاطلاع على جميع العناصر البالغ عددها 10 آلاف وقتًا طويلاً.

أريد حفظه على القرص ثم إجراء تبديل عشوائي على الملف باستخدام طريقة أخرى.

أي اقتراحات؟

هل كانت مفيدة؟

المحلول

كيف يتم تنفيذ روتينك العشوائي؟وخاصة روتين الصرف؟إذا كنت قد كتبت بنفسك، على هذا النحو:

vTempSrting := vStringList[I]; 
vStringList.Delete(I); 
vStringList.Insert(J,vTempString);

سيكون بطيئا جدا.استخدم طريقة التبادل في قائمة السلسلة.

استغرق هذا الرمز 78 مللي ثانية على جهاز الكمبيوتر العادي (عمره 3 سنوات):

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,Classes,uIntegerList,Windows,Math;

procedure Shuffle(aSL : TStringList);
var I,J : integer;
begin
  for I := 0 to aSL.Count-1 do
  begin
    J := randomrange(I,aSL.Count);
    aSL.Exchange(I,J);
  end;
end;

procedure CreateTestFile;
var
  vSL : TStringList;
  I : integer;
begin
  vSL := TStringList.Create;
  try
    for I := 1 to 100000 do vSL.Add('Sample text #'+inttostr(I));
    vSL.SaveToFile('c:\test.txt');
  finally
    vSL.Free;
  end;
end;

function TestShuffle : longword;
var
  vSL : TStringList;
  vTick0 : longword;
begin
  vSL := TStringList.Create;
  try
    vTick0 := gettickcount;
    vSL.LoadFromFile('c:\test.txt');
    Shuffle(vSL);
    vSL.SaveToFile('c:\test.txt');
    Result := gettickcount - vTick0;
  finally
    vSL.Free;
  end;
end;

begin
  CreateTestFile;
  writeln(TestShuffle,' ms');
  readln;
end.

نصائح أخرى

وإعادة ترتيب لstringlist في ذاكرة بطيئة، لذلك أود أن خلط قائمة مؤشر على أنها الأمثل الأولي.

وانا التخمين اخترت stringlist لتوفير الراحة للتحميل من وإنقاذ إلى القرص. يمكن للمرء أن يكون نهج أسرع لخلط فهرس. تقديم مجموعة من الأعداد الصحيحة 10000، خلط تلك، ثم استخدم متغير سلسلة مؤقت للاحتفاظ العنصر تبادل وإعادة ترتيب stringlist بك من أعلى إلى أسفل باستخدام القيم مؤشر تعديلا.

ويعيد كتابة الرئيسية سيوفر تحسينات أكبر، ولكن هذا قد يساعد إذا سلاسل الخاص بك ليست كبيرة جدا.

وطريقة سهلة لتوليد قائمة من الأرقام العشوائية، نوع، ومن ثم القيام مقايضة البشرى من البيانات في وقت لاحق. الفرز يمكن القيام به باعتباره س (ن * سجل (ن)) الخوارزمية، في حين مبادلة دائما هو س (ن) الخوارزمية، وبالتالي أسرع بكثير.

وفقط في حال كنت لم أفكر في ذلك، النظر إلى ترك البيانات كما هو، ومجرد حفظ مؤشر تعديلا إضافيا.

وسألت سؤالا قبل حول إنشاء مجموعة تعديلا - بدلا من توليد قائمة من الأرقام ومن ثم خلط لهم، كنت أرغب في وظيفة الذي كان قادرا على العودة بشكل متكرر على قائمة أرقام تعديلا، دون O (ن) تكلفة الذاكرة :

<لأ href = "HTTPS: //stackoverflow.com/questions/464476/generating-shuffled-range-using-a-prng-rather-than-shuffling">Generating مجموعة تعديلا باستخدام PRNG بدلا من خلط

إذا خلق نوع من مؤشر لملف على القرص، ثم يمكنك إنشاء نسخة تعديلا دون دفع تكلفة الذاكرة، والتي يمكن أن تكون هامة لملفات كبيرة جدا. لفهرس، أقترح شيئا بسيطا، مثل تيار ثابت من وظائف (إلى 32 أو 64 بت أعداد صحيحة) من بداية كل خط. وبهذه الطريقة، لاستخراج خط نطة من ملف نصي، يمكنك طلب ببساطة في مجرى مؤشر إلى N * 4 (أو N * 8 لمؤشرات 64-بت) لاكتشاف الإزاحة من بداية الخط، ومن ثم تسعى ل هذا الموقف في تيار ملف نصي وتلا خط.

وباستخدام هذا النهج، يمكنك خلط ملفات كبيرة للغاية، من دون دفع تكلفة في الذاكرة. بطبيعة الحال، سوف خلط يعني استخراج خطوط عشوائيا من الملف المصدر، والتي لن تكون فعالة كما في الذاكرة الفرز ما لم يكن ملف صغير جدا (تناسبها في ذاكرة التخزين المؤقت تقريبا على الوصول الأول) أو كبيرة جدا (الذي سحق الذاكرة حالة سوف تكون أسوأ من يسعى عشوائي)، أو ربما إذا كنت لا تستخدم القرص الصلب الميكانيكي (على سبيل المثال SSD).

لموقفك، 10K في الحقيقة ليست عددا كبيرا. شيء ما في المنطقة من 10 مليون خط، وربما الدخول في عدة غيغابايت من النص (اعتمادا على طول الخط وبطبيعة الحال)، سوف تكون أكثر تحديا، وحيث ان هذا النهج (أو شيئا من هذا القبيل) سيكون من الضروري في 32 بت.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top