Showing posts with label code. Show all posts
Showing posts with label code. Show all posts

Sunday, May 11, 2008

Linq: Composite keys don't work + Beware of ElementAt ...

I was trying to join two lists (one being a linq-to-sql result and the other being a List<> in memory) using a composite index. I tried doing it the right way, but it just didn't work. (By the way, the "right" way is really awkward. it means you must define a new anonymous type in both query, having the same fields. The best resource I found is here). So after the "right" way didn't work, I tried the more time-consuming way, which involves a Where inside another Where and turned out to be completely irrelevant performance-wise (~20K rows).

In the end, I had to do the join by myself. By chance, the two lists I needed to join had the exact same number of records, and the only thing I had to do was to make sure both lists are sorted in the same manner. Then I could just join each element in one list with the element at the same position in the second list. So the code looked something like that:

for (int i = 0; i < sWeights.Count(); i++)
{
double val = 0.0;
DateTime date = sWeights.ElementAt(i).Date;
while (i < sWeights.Count() && sWeights.ElementAt(i).Date.Equals(date))
{
val += sWeights.ElementAt(i).Weight * sChanges.ElementAt(i).Change;
i++;
}
// Do something with date and val
}




Now here's the deal - this code sucks! It takes AGES to complete. I searched MSDN for an indication about the running time of ElementAt, because I had a feeling this could be the problem - but it doesn't say anything about it. So I made a test - turned the two lists into arrays and ran using an array selector ([i]) and ... voila - the code completes in no time.



So now the code looks like this:


for (int i = 0; i < sWeights.Length; i++)
{
double val = 0.0;
DateTime date = sWeights[i].Date;
while (i < sWeights.Length && sWeights[i].Date.Equals(date))
{
val += sWeights[i].Weight * sChanges[i].Change;
i++;
}

// Do something with val
}




CONCLUSION: BEWARE - ElementAt DOES NOT guarantee anything about its running time, so if you need to run through the whole list, it's better to create an array with the list's elements and run over the array.

Monday, May 05, 2008

Can't this be simpler?

I'm trying to run a Linq query which, in SQL, would look like this:

select V.Date, SUM(F.Factor/V.Change) AS Denom
from AllVols V JOIN Factors F on F.Key = V.FId
group by V.Date



The only way I found looks like this:


var denoms = from v in allVols
join f in factors on v.FId equals f.Key
group new {v.Date, Factor = f.Value, v.Change} by v.Date
into g
orderby g.Key.Date
select new {g.Key.Date, Denom = g.Sum(d => d.Factor/d.Change)};




Is there no better way ?!?!

Wednesday, April 30, 2008

Linq Goodies 1 - Extracting a range from an array

Slowly but surely I'm starting to get the huge benefits Linq is bringing into our lives. Take a look at the following code snippet, which retrieves values from an array in a specified range:

var range = cData.Where((d, index) => index >= (i - 40) && index < (i));
Sweet!

Tuesday, December 04, 2007

A Killing IDE Feature I Would Like To See

A long time ago I used to use BugTrapper - an application that sits on the production server, records every instruction, and makes it possible to "play" everything back, step by step. It's a great tool to analyze bugs and especially crashes "post mortem", as long as it's not related to some obscure race condition (the overhead of using BugTrapper often ruling out the race in the first place).

I think there definitely is a case for applications like this, and the fact that Mutek hasn't been able to push itself farther into developers' awareness is quite surprising to me.

The feature I would like to see in an IDE is a mini-BugTrapper. I would like the IDE to be able to record up to a certain amount of instructions (say up to 100,000) during debugging. How many times did you stop at some breakpoint and suddenly realized you should have put this breakpoint a little bit earlier in the flow? You really need to see  the value of some parameter, or the actually executed flow, a few steps back - but you can't. The only thing the IDE gives you is the static current call stack - which just isn't enough. You want to know what variables caused you to get into that current call stack, but that's beyond the scope of the IDE's features.

That's, IMHO, a killing feature that could significantly boost debugging time.

Sunday, December 02, 2007

Is GOTO always evil?

The other day I decided to use a "goto" statement in my C# code. It was a difficult decision to take, and was primarily motivated by the need for readability.

Apparently, Linus Torvalds also thinks there are cases where "goto" is appropriate, so I'm in good company...

Thanks to Scott Hanselman for pointing to this thread.

Tuesday, November 13, 2007

VB Grrrrrr...

Yet another MSDN and .NET WTF:

I'm currently implementing some temporary code that was written in VB into our C# infrastructure (let's skip the details). Anyway, there are parts in the VB code that I would like to group because either they are currently not being used, or for some reason I want to hide it from view and get to it at some later phase.

Obviously, a #Region directive seems like the best solution.

My VB is quite rusted, but using common sense I tried using  the same syntax I'm used in C#. But alas - it didn't work. So I searched MSDN - hey, it should work! Well, VB have this little difference that the identifier_string MUST exist and it must be surrounded by quotation marks. OK, no biggy, I usually put it there anyway.

But why doesn't it work?

Well, there is this tiny little limitation, hidden from you if you rely solely on MSDN, that "'#Region' and '#End Region' statements are not valid within method bodies."

Which raises two questions:

1. Why, in Heaven's name, should there be such a difference between C# and VB. It's just a freaking compilation directive!

2. Assuming there is some justified reason for that (which I doubt - I guess it's just a non-implemented feature) - would it hurt someone to put this info in MSDN so I won't have to get crazy trying to figure out why it doesn't work?!?!

And now to a personal to-remember note:

I relied solely on Intellisense and Resharper to know the code is wrong. I'm using the C# only version of Resharper, so I have no idea whether Resharper would have been more helpful. Anyway - had I compiled from the beginning (or at least looked at the message Intellisense gave me) - I would have seen much sooner why it doesn't work...

Tuesday, October 16, 2007

I don't understand the implementation of System.Double

Take a close look at the implementation of System.Double (use Reflector or any other dissassembler).

Look, for example, at the following excerpt:

public const double PositiveInfinity = (double)1.0 / (double)0.0;
public const double NaN = (double)1.0 / (double)0.0;

 


Huh?!?! What ?!!? Why ?!?!


Of course, I had to run and check:

double myNaN = double.NaN;
bool isInf = (double.IsPositiveInfinity(myNaN));
// isInf is set to FALSE

double myInf = double.PositiveInfinity;
bool isNaN = (double.IsNaN(myInf));
// isNaN is set to FALSE

 


It doesn't end there. Look at the implementation of IsNaN:

public static bool IsNaN(double d)
{
return (d != d);
}

 


All'n'all, I must confess I can't make any sense of all this!


I promise to publish if/when I do.

Tuesday, September 18, 2007

Impersonating data types

I've already talked about things I'm missing in C#/CLR (here and here). I'd like to add a new concept I would call "impersonation".

Let's start with a simple example:

Say I have a method that calculates the sum of some array of doubles (double[]), like so:

public static double Sum(double[] list)
{
double sum = 0.0;
for (int i = 0; i < list.Length; i++)
{
sum += list[i];
}
return sum;
}

Now I would like to use this method with an input that is not an array of doubles, but some other list of double values (say List<double>, a RowCollection, whatever).


The straight-forward solution is to change the Sum method to receive a collection instead of an array, or make it a template method. But that's when I can change it! What if the method belongs to some class that is not under my jurisdiction?


In this case, the only solution I can think of is to create a whole new array of doubles based on the collection you want to work with. But of course, that's not what I want! First, it costs time and memory. Second, if the Sum method would also change the actual values in the array - you're lost. In my case, it's the first restriction that bugs me.


If the input variable was something else than an array (some class), in most cases you would be able to solve it by inheriting from it and feeding the child class to the method. But then again it wouldn't work for all cases. First because the lack of multiple inheritance (sigh) could restrain you from such solution. Second, in the case the input variable is of some sealed type.


My solution (proposal) - impersonation.


A possible implementation would be an attribute on the class that indicates to the compiler that an object of this type could be used to substitute some other type. For example:

[Impersonate(typeof(double[]))]
public class MyCollection
{
// Implement the parts of double[] you are going to need
}

 


Note that in theory, one could implement in MyCollection only those parts of Array that might indeed be called. Then the call to the method could be done as so:

MyCollection myCollection = new MyCollection();
double sum = Sum(myCollection);

 


And, of course, the compiler should be able to understand the attribute and not generate any errors. Unless, of course, the Sum method uses some features of Array that are not implemented in MyCollection .


Lastly, I would allow multiple impersonations on the same class.

Sunday, September 16, 2007

Asymmetric Accessor Accessibility in C#

Today I wanted to define one accessor with two different accessibility levels. That is, I wanted a property to have public 'get' access and private 'set' access. I remembered that in .NET 2.0 this became possible, but didn't remember exactly the syntax. So I tried first my intuition, which was:

public DataTable MyTable
{
get { return myTable; }
}

private DataTable MyTable
{
set { myTable = value; }
}

Unfortunately, I was wrong. A quick search revealed the secret syntax:

public DataTable MyTable
{
get { return myTable; }
private set { myTable = value; }
}

 


More details in the MSDN entry.

Thursday, August 30, 2007

Running the same application as Windows Application and Console Application

Say you have a Windows Application (i.e. with GUI and all), and you want to add to it the option to be executed as a Console Application as well. Here are the two steps necessary:

1. Adding Console Application support

You must create your application as a Windows Application. Then open the Project Properties, and under the Application tab set the "Output type" to "Console Application". Once this is set, you must update your Main function to support dual application types. By default, when you create your application as a Windows application, your Main looks like this:

static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}



To support both Console Application and Windows Application, you must change it. For example, you can decide that if it receives as sole argument the string "OpenForm" it will open as a Windows Application, otherwise as a simple Console Application (in which case you'll probably want to take care of the arguments). So you should change your Main as so:


static void Main(string[] args)
{
if (args.Length == 1 && args[0] == "OpenForm")
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
// TODO: Take care of arguments
Console.WriteLine("This is a console application");
}
}



2. Remove the annoying background console


The above code is nice, but has one annoying side-effect - when you open the application as a Windows Application, you constantly have a console open in the background (closing it will close your form). To work around this you must reopen the application (i.e. creating a new process) with the console hidden. This is done as so:


static void Main(string[] args)
{
if (args.Length == 0)
{
Process current = Process.GetCurrentProcess();
string fileName = current.MainModule.FileName;
ProcessStartInfo si = new ProcessStartInfo(fileName, "OpenForm");

si.CreateNoWindow = true;
si.RedirectStandardError = true;
si.RedirectStandardOutput = true;
si.UseShellExecute = false;
Process.Start(si);
}
else if (args.Length == 1 && args[0] == "OpenForm")
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
// TODO: Take care of arguments
Console.WriteLine("This is a console application");
}
}



Explanation:

The assumption is that if you want the application to run as a Windows Application, it doesn't need any argument (though this could also be done easily if required). So if the application starts with no arguments, it will create a new process of itself (through the MainModule we extract the running process' file name), but this time with no console in the background (all the settings on the ProcessStartInfo object). This time, it is called with an argument that knows to load the form (the "OpenForm" argument).



The result is an application that can be run both as Windows Application and Console Application. When you run it as a Windows Application there is a console that opens and closes immediately in the background, but that's all.


Thanks to Ami Bar for helping me with the second step.

Maintainability

A short while ago Oren Eini stated that in his opinion, the only metric that counts is Maintainability. He even gave an excellent way to measure it.

;-)

Ever since I read these two posts, I've been trying to find ways to concretely prove him wrong. The farthest I got was with Performance, where you may have good reasons to improve performance at the expense of harming maintainability. But in good code, this is done only if the improved performance are part of the requirement. In this case, you've got to measure the code compared to some other alternative that still meets the requirement - leaving you once again to measure maintainability only.

My tiny addition to Oren's statement would be - as long as the requirements are fulfilled.

Thursday, August 23, 2007

Each line of code should do one thing

I was writing some code today that looks like this:

int counter = 0;
while (/* some condition */)
{
// Do some formatting
counter++;
FormattingProcessStatus(counter);
}

Now I could have done it differently like so:
int counter = 0;
while (/* some condition */)
{
// Do some formatting
FormattingProcessStatus(++counter);
}

which would have "saved" me one line of code. I hate this - I always have. Ever since I started learning C/C++ (over a decade ago) and while trying to solve an exercise discovered a situation where two different compilers generated different results. But today, for the first time, I understood why I hate it so much - it's against a very basic rule that EACH LINE OF CODE SHOULD DO ONE THING.



This is a very simple rule I don't remember having read anywhere, but it's the basis for readable code. Writing code, and even more so - reading code, requires a lot of brain effort. You need to be able to see the whole architecture, and how that particular object and method fits in. Sometimes you need to keep a whole stack of variables (state) in mind to really understand what's going on, etc. The difference between having to read a line that does one single thing and reading a line that does more - is very big, and complicates the reading of the code exponentially.


So if you want your code to be readable - start by making sure each line does exactly one thing!