Showing posts with label surprised. Show all posts
Showing posts with label surprised. Show all posts

Saturday, August 30, 2008

GetHashCode() have been changed

As its written in MSDN (http://msdn.microsoft.com/en-us/library/system.string.gethashcode.aspx):
Remarks:
The behavior of GetHashCode is dependent on its implementation, which might change from one version of the common language run-time to another. A reason why this might happen is to improve the performance of GetHashCode.

In the following versions exactly this happens:



  • 2.0.50727.3053

  • 2.0.50727.1433


Let's say you like to do something for load-balancing based on the following code:




return Math.Abs((key.GetHashCode() % serverAmount));



it will return a different server node in case of shared cache. To handle this issue we have added 2 things, first of all is an alternative hashing algorithm and second we check the run-time between clients and server and inform clients about it in case this happens.



If you are using a version of shared cache which is below 2.0.3.276 you need to keep all your systems up-to-date with the same CLR version or you decide to use a different hashing algorithm for your system. Within our notifier program you can check this quite easily.

To use following options you will firstly need to register, the registration can be done during installation or afterwards within a new option within menu context of SharedCache.com Notify application.

  • Check if all environments are using same CLR


  • A Test to check if you able to use all Hashing Algorithms



  • Get Informed if your environment is using same version of shared cache, this is mostly important to grant all communication options between clients and caching nodes on your servers.


for more information about hashing algorithms which are supported by shared cache visit my website: http://www.sharedcache.com/ - or go directly to http://www.sharedcache.com/cms/shared_cache_notify.aspx

Friday, February 22, 2008

consider to use local variables in some cases

who said performance == performance?

If you visited this blog already you now that indeXus.Net Shared Cache Server part is developed now as an asynchronous server and not a thread per client model. One of the very central server methods is to receive data. For this we have the following one:
private void ReadCallback(IAsyncResult ar)

{
// some code int read = handler.EndReceive(ar);
if (read > 0)
{
Monitor.Enter(state);
for (int i = 0; i <>
{
state.DataBuffer.Add(state.Buffer[i]);
}
Monitor.Exit(state);
// .
// .
// .
// .
// some more code
}

The above loop is developed straightforward, take the received buffer and concatenate it to the actual List until you received all needed data from the client. Well done - works great - but its slow like hell !!!!

Lets do some re-factoring and save up to 2.5 sec. which is actually for the tested use case 27,2% of end-to-end time:
adding 1000 objects with approx. 100kb toke 10,251 sec. in average (100 runs) - after this change we ended up with 7,456 sec for the same case in average for also 100 runs.

private void ReadCallback(IAsyncResult ar)
{
// some code
int read = handler.EndReceive(ar);
if (read > 0)
{
Monitor.Enter(state);
// save 2.5 seconds while i copy data to local variables and i do not access the property
byte[] localBuffer = new byte[state.DataBuffer.Count];
localBuffer = state.Buffer;
List localList = new List();
localList.AddRange(state.DataBuffer);
// copy all buffer data into DataBuffer which is list and contains all data until we get the whole message.
for (int i = 0; i < read; i++)
{
localList.Add(localBuffer[i]);
}
state.DataBuffer = localList;
Monitor.Exit(state);
// .
// .
// .
// .
// some more code
}

My conclusion is simple, keep attention were do you access object properties. I'm pretty sure that in 99% of all use cases it would not matter but here, its an amazing result for today's session.

Wednesday, March 14, 2007

surprise: int.TryParse(xx,yy)

I really get surprised about the following behaviour:

when I've tried to use the follwoing line of code:

if(!int.TryParse(row["myRowName"] as string, out myDefinedInt))

tryParse always returned me false and I assinged a default value. After making sure that all my rows have values for myRowName I were confused.

a friend suggested to use row["myRowName"].ToString() and voila it worked like i wanted.

I didn't really figured out why that happens, then in none of my cases the value were empty that my expression as string would return null.

here a bit more code:

DataSet data = DataReader.GetData();
DataTable tab = data.Tables["MyTableName"];
DataView view = tab.DefaultView;

view.RowFilter = "RowNameA LIKE '%" + valA + "%' AND RowNameB LIKE '%" + valB + "%'";

if (view.Count > 0)
{
Data.MyDataObject item;
foreach (DataRowView row in view)
{
item = new Data.MyDataObject();
item.SomeValue1 = row["SomeValue1"] as string;
item.SomeValue2 = row["SomeValue2"] as string;
int outData = -1;
if (!int.TryParse(row["SomeValue3"].ToString(), out outData))
{
item.SomeValue3 = 40;
}
else
{
item.SomeValue3 = outData;
}

etc ... etc ... etc ...

Thanks to richi (Y)

Shared Cache - .Net Caching made easy

All information about Shared Cache is available here: http://www.sharedcache.com/. Its free and easy to use, we provide all sources at codeplex.

Facebook Badge