What is the difference between myDataSet.Tables[0] and myDataSet.Tables["myTable"] ??

  • Thread starter Thread starter zhivago
  • Start date Start date
Z

zhivago

I figured both would behave identical:

myDataSet.Tables[0]

and

myDataSet.Tables["myTable"]


What's the difference?
 
They will only behave identically if myTable is the first DataTable in
myDataSet.Tables.

myDataSet.Tables[0] will return the first DataTable in myDataSet.Tables.

myDataSet.Tables["myTable"] will return myTable regardless of it's position
in myDataSet.Tables, assuming that it does, indeed, exist in
myDataSet.Tables.
 
There is a big difference performance-wise. Tables(0) is bound at
compile-time. Tables("MyTable") is bound at runtime and can take 200 times
longer to execute (at least in my tests).

--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
INETA Speaker
www.betav.com/blog/billva
www.betav.com
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no rights.
__________________________________
Visit www.hitchhikerguides.net to get more information on my latest book:
Hitchhiker's Guide to Visual Studio and SQL Server (7th Edition)
and Hitchhiker's Guide to SQL Server 2005 Compact Edition (EBook)
 
William (Bill) Vaughn said:
There is a big difference performance-wise. Tables(0) is bound at
compile-time.

What exactly do you mean by being "bound at design time"?

Tables("MyTable") is bound at runtime and can take 200 times
longer to execute (at least in my tests).

Yep, it has to be considerably slower. Depends on what approach is used
(hashtable, list, etc.)
 
By "binding" (in this case) I mean the compiler takes the code reference (to
the DataTable) and inserts a fixed address of the start of the DataTable
structure at design time when it knows the location (as in Tables(0)). If
the compiler cannot determine the specified DataTable at compile time, it
inserts code to look up the table in the Tables collection at runtime--each
time it's referenced using a string or string variable. I discuss the
details of this in my book.

--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
INETA Speaker
www.betav.com/blog/billva
www.betav.com
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no rights.
__________________________________
Visit www.hitchhikerguides.net to get more information on my latest book:
Hitchhiker's Guide to Visual Studio and SQL Server (7th Edition)
and Hitchhiker's Guide to SQL Server 2005 Compact Edition (EBook)
 
William (Bill) Vaughn said:
By "binding" (in this case) I mean the compiler takes the code reference
(to the DataTable) and inserts a fixed address of the start of the
DataTable structure at design time when it knows the location (as in
Tables(0)).

It references the first item in DataTable collection, right? Isn't this the
same for every list?
 
Tables(0) references the first Table in the collection, but Tables("Fred")
has to look up Fred at runtime (search for a match on the string by table
name).

--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
INETA Speaker
www.betav.com/blog/billva
www.betav.com
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no rights.
__________________________________
Visit www.hitchhikerguides.net to get more information on my latest book:
Hitchhiker's Guide to Visual Studio and SQL Server (7th Edition)
and Hitchhiker's Guide to SQL Server 2005 Compact Edition (EBook)
 
Hi Bill,

That is a hug amount of time, do you think that in that time I can go from
here to Redmont and back by plane? (Before it is not understand by
somebody, I mean 200 times is quiet relative).

:-)

Cor
 
Hi there,

I would in some respect disagree with Wiliams reply. Especiallly with:
inserts a fixed address of the start of the DataTable
structure at design time when it knows the location (as in Tables(0))

Addresses are known at the runtime. The only thing fixed in this case is
offset from the location referenced by arraylist that holds the pointers to
tables. This is disassembled and translated code for both iterators from the
System.Data assembly:

public DataColumn get_Item(int index)
{
DataColumn column1;
try
{
column1 = (DataColumn) this._list[index];
}
catch (ArgumentOutOfRangeException)
{
throw ExceptionBuilder.ColumnOutOfRange(index);
}
return column1;
}

public DataColumn get_Item(string name)
{
if (name == null)
{
throw ExceptionBuilder.ArgumentNull("name");
}
DataColumn column1 = this.columnFromName[name] as DataColumn;
if (column1 == null)
{
int num1 = this.IndexOfCaseInsensitive(name);
if (0 <= num1)
{
return (DataColumn) this._list[num1];
}
if (-2 == num1)
{
throw ExceptionBuilder.CaseInsensitiveNameConflict(name);
}
}
return column1;
}

internal int IndexOfCaseInsensitive(string name)
{
int num3 = this.table.GetSpecialHashCode(name);
int num2 = -1;
DataColumn column1 = null;
for (int num1 = 0; num1 < this.Count; num1++)
{
column1 = (DataColumn) this._list[num1];
if ((((num3 == 0) || (column1._hashCode == 0)) ||
(column1._hashCode == num3)) && (base.NamesEqual(column1.ColumnName, name,
false, this.table.Locale) != 0))
{
if (num2 == -1)
{
num2 = num1;
}
else
{
return -2;
}
}
}
return num2;
}



As you can see both methods DataTableCollection[Int32] and
DataTableCollection[String] follow the same path and the end result is always
this._list[index] which behind the scenes should be equivalent to address
(this._list->InternalArray) + index * sizeof(DataTablePointer), where
sizeof(DataTablePointer) = 4. The only difference between this method is that
offset for Tables[0] is known, so the only thing runtime must do is to jump
to the location pointed by this._list->InternalArray (and get next 4 bytes
which actually is a pointer to the datatable), whilst second method must
obtain offset by hastable lookup (or if it fails looping over items comparing
table name), that's why the second method is slower. Therefore i disagree
with statement
If the compiler cannot determine the specified DataTable at compile time, it
inserts code to look up the table in the Tables collection at runtime --each
time it's referenced using a string or string variable.

Hope my reasoning doesn not look chaotic :)

Regards

--
Milosz Skalecki



William (Bill) Vaughn said:
By "binding" (in this case) I mean the compiler takes the code reference (to
the DataTable) and inserts a fixed address of the start of the DataTable
structure at design time when it knows the location (as in Tables(0)).If
the compiler cannot determine the specified DataTable at compile time, it
inserts code to look up the table in the Tables collection at runtime --each
time it's referenced using a string or string variable. I discuss the
details of this in my book.

--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
INETA Speaker
www.betav.com/blog/billva
www.betav.com
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no rights.
__________________________________
Visit www.hitchhikerguides.net to get more information on my latest book:
Hitchhiker's Guide to Visual Studio and SQL Server (7th Edition)
and Hitchhiker's Guide to SQL Server 2005 Compact Edition (EBook)
 
Yea, this is a LOT clearer--especially for those that understand the code
behind the scenes. I still like my more simplistic approach. The bottom line
is that if you reference objects by string, it takes far longer to get the
address resolved.

--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
INETA Speaker
www.betav.com/blog/billva
www.betav.com
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no rights.
__________________________________
Visit www.hitchhikerguides.net to get more information on my latest book:
Hitchhiker's Guide to Visual Studio and SQL Server (7th Edition)
and Hitchhiker's Guide to SQL Server 2005 Compact Edition (EBook)
-----------------------------------------------------------------------------------------------------------------------

Milosz Skalecki said:
Hi there,

I would in some respect disagree with Wiliams reply. Especiallly with:
inserts a fixed address of the start of the DataTable
structure at design time when it knows the location (as in Tables(0))

Addresses are known at the runtime. The only thing fixed in this case is
offset from the location referenced by arraylist that holds the pointers
to
tables. This is disassembled and translated code for both iterators from
the
System.Data assembly:

public DataColumn get_Item(int index)
{
DataColumn column1;
try
{
column1 = (DataColumn) this._list[index];
}
catch (ArgumentOutOfRangeException)
{
throw ExceptionBuilder.ColumnOutOfRange(index);
}
return column1;
}

public DataColumn get_Item(string name)
{
if (name == null)
{
throw ExceptionBuilder.ArgumentNull("name");
}
DataColumn column1 = this.columnFromName[name] as DataColumn;
if (column1 == null)
{
int num1 = this.IndexOfCaseInsensitive(name);
if (0 <= num1)
{
return (DataColumn) this._list[num1];
}
if (-2 == num1)
{
throw ExceptionBuilder.CaseInsensitiveNameConflict(name);
}
}
return column1;
}

internal int IndexOfCaseInsensitive(string name)
{
int num3 = this.table.GetSpecialHashCode(name);
int num2 = -1;
DataColumn column1 = null;
for (int num1 = 0; num1 < this.Count; num1++)
{
column1 = (DataColumn) this._list[num1];
if ((((num3 == 0) || (column1._hashCode == 0)) ||
(column1._hashCode == num3)) && (base.NamesEqual(column1.ColumnName, name,
false, this.table.Locale) != 0))
{
if (num2 == -1)
{
num2 = num1;
}
else
{
return -2;
}
}
}
return num2;
}



As you can see both methods DataTableCollection[Int32] and
DataTableCollection[String] follow the same path and the end result is
always
this._list[index] which behind the scenes should be equivalent to address
(this._list->InternalArray) + index * sizeof(DataTablePointer), where
sizeof(DataTablePointer) = 4. The only difference between this method is
that
offset for Tables[0] is known, so the only thing runtime must do is to
jump
to the location pointed by this._list->InternalArray (and get next 4 bytes
which actually is a pointer to the datatable), whilst second method must
obtain offset by hastable lookup (or if it fails looping over items
comparing
table name), that's why the second method is slower. Therefore i disagree
with statement
If the compiler cannot determine the specified DataTable at compile time,
it
inserts code to look up the table in the Tables collection at
runtime --each
time it's referenced using a string or string variable.

Hope my reasoning doesn not look chaotic :)

Regards
 
Back
Top