Recent

Author Topic: [Answered]Which is faster? DataSet.Fields[Index].AsString or TField.AsString?  (Read 13484 times)

Knipfty

  • Full Member
  • ***
  • Posts: 230
Hi,

If I assign a DataSet.Fields[0] object to a TField object which then processes faster?

Code: [Select]
Procedure MyTest;
var
  MyField: TField;
  S: string;
begin
  DataSet.Active := true;
  MyField := DataSet.Fields[0];
  DataSet.First;
  while not DataSet.EOF do
  begin
    S: = DataSet.Fields[0].AsString;
    // or
    S: = MyField.AsString;
    DataSet.Next
  end;
  DataSet.Active := false
end;

Or are they about the same?

Thanks

Knipfty
« Last Edit: August 31, 2012, 03:56:31 am by Knipfty »
32-bit Lazarus 1.0 FPC 2.6.0, 64-bit Win 7, Advantage DB 10.10

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Which is faster? DataSet.Fields[Index].AsString or TField.AsString?
« Reply #1 on: August 30, 2012, 07:30:59 pm »
I would imagine the compiler could optimize that as you are using a fixed index number (0). Don't know whether it does.

Disclaimer: definitely not a compiler expert here ;)
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

Knipfty

  • Full Member
  • ***
  • Posts: 230
Re: Which is faster? DataSet.Fields[Index].AsString or TField.AsString?
« Reply #2 on: August 30, 2012, 07:35:59 pm »
The key here is that both are pointing to the same object.  So which one resolves faster?  I know FieldByName is much slower.  I actually have code that looks like this right now:

Code: [Select]
LeftStr(DS.Fields[Fld[0]].AsString,L[0])
and am wondering if this would be any faster

Code: [Select]
LeftStr(MyField.AsString,L[0])
Assuming that I assigned MyField like the above example.
32-bit Lazarus 1.0 FPC 2.6.0, 64-bit Win 7, Advantage DB 10.10

eny

  • Hero Member
  • *****
  • Posts: 1609
Re: Which is faster? DataSet.Fields[Index].AsString or TField.AsString?
« Reply #3 on: August 30, 2012, 08:08:26 pm »
I'm guessing that the difference in execution time is neglectable because of the slowness of the disk I/O.
All posts based on: Win10 (Win64); Lazarus 2.0.10 'stable' (x64) unless specified otherwise...

ludob

  • Hero Member
  • *****
  • Posts: 1173
Re: Which is faster? DataSet.Fields[Index].AsString or TField.AsString?
« Reply #4 on: August 30, 2012, 08:40:06 pm »
You save a call to GetField when doing S: = MyField.AsString; The compiler doesn't optimise it away (on win32 at least).  So it is faster. You'll notice the difference when all the data are already in memory (TSQlQuery.PacketRecords=-1 or in memory datasets)

teos

  • Full Member
  • ***
  • Posts: 147
Re: Which is faster? DataSet.Fields[Index].AsString or TField.AsString?
« Reply #5 on: August 30, 2012, 09:45:55 pm »
MyField.AsString is faster. Dataset.fields[0].AsString requires searching.

Another optimalisation: MyField.Value is faster than asString because asString require checking and converting. If you know if the field is string or integer, it's faster to use the content of the field as such.

Knipfty

  • Full Member
  • ***
  • Posts: 230
Re: Which is faster? DataSet.Fields[Index].AsString or TField.AsString?
« Reply #6 on: August 30, 2012, 09:53:43 pm »
@teos
Quote
If you know if the field is string or integer, it's faster to use the content of the field as such.

What would this look like?  I am only familiar with .AsString or .AsInteger.  Are you referring to .Text or .Value?
32-bit Lazarus 1.0 FPC 2.6.0, 64-bit Win 7, Advantage DB 10.10

taazz

  • Hero Member
  • *****
  • Posts: 5365
Re: Which is faster? DataSet.Fields[Index].AsString or TField.AsString?
« Reply #7 on: August 31, 2012, 01:17:36 am »
In short doing DataSet.Fields[0].AsString will execute the getter function to find and return the field at index 0 this is fast enough to not be noticed but it it faster if you do keep a reference of the field and not execute one more function inside the loop.

As for the .AsString or .AsInteger or .Value it is faster to use the method that returns the natural data directly so for a string field .AsString will always be faster than .Value since .Value converts the data in to a variant as well (ee calls a convertion function every time you do VariantVariable := StringVariable), for an integer field .AsInteger is faster etc..


Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Knipfty

  • Full Member
  • ***
  • Posts: 230
Re: Which is faster? DataSet.Fields[Index].AsString or TField.AsString?
« Reply #8 on: August 31, 2012, 03:55:57 am »
Hi taazz,

I didn't think that .Value was the way to go.  I need the data in String format, so .AsString will be just fine.  I've converted all by .FieldByName that are in loops over to TField.

Knipfty
32-bit Lazarus 1.0 FPC 2.6.0, 64-bit Win 7, Advantage DB 10.10

gato2707

  • New Member
  • *
  • Posts: 42
I tested those differnet approaches long time ago with delphi 7.

I agree than TField as Tdatatype is faster than DataSet.Fielda[index].AsDataType and the worst of them is using .Value, except in a special times, when is better option leave convertion tasks to the compiler.

Anyway if you are using remote databases, you will get slow access times.

But there are a couple things than really makes a difference:

1) Disable any TDataset controls before use TFields, and enable them after task are completed.

2) Mix wisely direct SQL commands with TFields tasks.

 

KpjComp

  • Hero Member
  • *****
  • Posts: 680
If you know the type of field, you can also map the fields to there proper persistent field type.

eg.
Code: [Select]
var
  MyField:TStringField;
  S:string;
begin
  MyField := dataset.fieldbyname('somestringfield') as TStringField;
  //some tight loop
  ..
     S := MyField.Value;  //here you can still use value, it's no longer a variant.
end;

Advantages here is that you can now use Value again, it maps directly to a String now.
Also handy for BlobFields, as you will also get LoadFromFile / LoadFromStream etc..

teos

  • Full Member
  • ***
  • Posts: 147
If you know the type of field, you can also map the fields to there proper persistent field type.

eg.
Code: [Select]
var
  MyField:TStringField;
  S:string;
begin
  MyField := dataset.fieldbyname('somestringfield') as TStringField;
  //some tight loop
  ..
     S := MyField.Value;  //here you can still use value, it's no longer a variant.
end;

Advantages here is that you can now use Value again, it maps directly to a String now.
Also handy for BlobFields, as you will also get LoadFromFile / LoadFromStream etc..


But it will cost you speed again, because of the search.

If I'm correct, fields are accessible as objects. Dataset1Stringfield1.Text is shorter.

KpjComp

  • Hero Member
  • *****
  • Posts: 680
But it will cost you speed again, because of the search.

There is no speed problems, how you assign to your persistent fields is up to you.

I assign all fields at the beginning, so it's only done once, my example showed you inside the procedure, but this was only for simplicity, but even here inside the tight loop you are going to be getting Full Speed, there is no search.

Knipfty

  • Full Member
  • ***
  • Posts: 230
OK.  So here is a stupid question.  I've now seen in this thread, TFloatField and TStringField.  Is there a T<fieldtype>Field defined for each ft<type>, as in ftFloat and ftString?  And are all these documented on one page somewhere?

I've found this link http://www.freepascal.org/docs-html/fcl/db/tfieldtype.html but no summary of  T<fieldtype>Field.

Thanks
32-bit Lazarus 1.0 FPC 2.6.0, 64-bit Win 7, Advantage DB 10.10

taazz

  • Hero Member
  • *****
  • Posts: 5365
All basic field classes are defined in the DB.pas unit, now how they are mapped to the TfieldType enum is something only the database specific components would know. In order to apply their own translation of TFieldType to TfieldClass they have to override the GetFieldClass method of TDataset and there is a default mapping which is defined as a const array inside the DB.pas unit with the name DefaultFieldClasses. It is already in the interface section of the unit so you have access to it from your code if that is required.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

 

TinyPortal © 2005-2018