burkleyd wrote:
> --- In [email protected], Bembi Prima <bembi.pr...@...> wrote:
>> Hi all, i have a weird problem..
>> i am trying to make a program with big arrays, but it always crashes with
>> out of memory error even though the computer has 2GB memory and i've
>> maximized the pagefile. from task manager i notice that total physical
>> memory usage never exceed 60% when my program is running. why this keeps
>> happening? i don't know what else to do..
>>
>> one more question, is there a faster method than a simple loop to find the
>> indexes of a certain number in an array?
>> for example, if i have an array [2, 3, 5, 7, 9, 5, 11, 5, 5], and i want to
>> find 5 in that array, the method should return the indexes where the element
>> is 5, which is [2, 5, 7, 8]. i still use a simple check every element method
>> and i think it takes a significant amount of time if the array is so big.
> 
> I'm not 100% sure this will work in Delphi.
> I know that it does in another programming language
> that I use. The creator of that compiler loosely
> based it on VB. BUT... he also added some components
> that Delphi based. And that's how I know that this
> "might" be possible in Delphi.
> 
> Here's how I've handle this kind of problem before...
> 
> I move the numeric array into a "MemoryStream".
> Set the "Position" back to 0 (zero).
> 
> Then "Read" (x number) of bytes, at a time, into a
> variable.
> 
> If that variable matches my criteria... I store the
> Position of the MemoryStream in a holding array and
> then use the holding array as indexes into the numeric
> array. To keep the speed optimal... I only check for
> the minimum criteria that I need.
> 
> When I store the Position... I first subtract the
> (x number) of bytes, that are being read, from the
> Position and then divide it by the (x number) of
> bytes.
> 
> For instance... if you are reading LongInt's from the
> MemoryStream in a "Do" loop... every time you found a
> match to your criteria you'd store the position as an
> equation that looks something like...
> 
> pos := (MemoryStream.Position - 4) / 4
> 
> This has proven to be alot faster than a For/Next
> loop (at least for me it has).

I cannot imagine how that could possibly be faster than a loop that 
reads the array directly.

Reading four bytes out of a stream is guaranteed to be slower than 
reading four bytes out of an array.

Calculating the location from the current stream position is guaranteed 
to be slower than using the array index that you would already have if 
you were iterating over the loop directly.

I can only conclude that the language and compiler you used had 
atrociously bad implementations of arrays or loops.

Compare the following. Assume RecordResultIndex stands for whatever is 
necessary to add the given array index to the list of results.

var
   Value: Integer;
   Location: Integer;
begin
   for Location := 0 to Pred(Length(Haystack)) do begin
     Value := Haystack[Location];
     if Value = Needle then
       RecordResultIndex(Location);
   end;
end;


var
   HaystackStream: TStream;
   Value: Integer;
   Location: Integer;
   Size: Integer;
begin
   HaystackStream := TMemoryStream.Create;
   try
     Size := Length(Haystack) * SizeOf(Integer);
     HaystackStream.Write(Haystack[0], Size);
     HaystackStream.Position := 0;
     while HaystackStream.Position < Size do begin
       HaystackStream.Read(Value, SizeOf(Integer));
       if Value = Needle then begin
         Location := (HaystackStream.Position - SizeOf(Integer))
                     div SizeOf(Integer);
         RecordResultIndex(Location);
       end;
     end;
   finally
     HaystackStream.Free;
   end;
end;


So you see how the latter does all the same things as the former, plus a 
*lot* more?

-- 
Rob

Reply via email to