July 30, 2008

Data Dynamics Support Forum Super Search

In addition to the custom Google search for searching Data Dynamics Reports help files, I've added another custom search for Data Dynamics Support Forums. Once you're search results are shown you can also refine the results by each of our products: Data Dynamics Reports, Data Dynamics Analysis, ActiveReports, ActiveBar, ActiveReports (ActiveX/COM/VB6), DynamiCube, or SharpGraph.


Give it a try using the gadget below:


July 28, 2008

Obama Extends an Open Invitation to the Democratic National Convention

A Special Invitation from Barack
Want a free ticket to the DNC? Obama will give you one. A leader who tries to engage everyone. That's a new concept in American politics, and I like it.

July 26, 2008

Performance & The Golden Hammer: Linq

I recently read tiredblogger's IQueryable Methods on ActiveReports ControlCollections post. First of all, I can see how the "find control by name" type of method to our control collection would certainly be useful. We should look at adding it in an efficient way that won't impose overhead when it isn't needed. However, I do have some suggestions that might help in this scenario.

Most importantly, you're not stuck catching exceptions. Allowing exceptions to be thrown is extremely slow, and in the first example tiredblogger noted, this is probably the cause of "destroying performance". If there are hundreds of "indicators" in his example, there may be several to several hundred exceptions being thrown. However, I want to get right into "Linq" and using it as a solution in this case...

In cases such as this, I don't think Linq is appropriate. First, I think it is helpful to define exactly what "Linq" is. There are lots of idioms associated with Linq which I don't think are Linq at all, namely Extension Methods and Lambda Expressions. Both of which Linq relies on heavily, but are not really Linq. Don't get me wrong though, they are extremely useful (arguably more useful than Linq itself), just not really Linq. At its essence, Linq is the language integrated query facility and IQueryable/IQueryable<T> and goes through IQueryProvider and the various IQueryProvider implementations.

It is very interesting to understand what these extension methods are really doing in order to take full advantage of them. Their concise syntax can mislead us into thinking their "query-like" nature are some how performant in scenarios where they are not. In this example the whole interaction with Linq comes down to IQueryable<Label> (where Label happens to be an ActiveReports Label) and the use of SingleOrDefault.

So my first thought was that, SingleOrDefault has no state between each call to it during that loop, so in the best case it is doing a search through the controls list. Another thing might be to just fill up a Dictionary<string,ARControl> with controls keyed by name before doing the loop. With hundreds of indicators the Diciontary<T> lookup should be much faster than repeatedly searching through the control collection with SingleOrDefault. Essentially this comes down to replacing the code to convert/wrap List<T> with an IQueryable<T> instance to convert the List<T> into a Dictionary<T>.

To satisfy my own curiosity, I did some quick testing and as it turns out the point of IQueryable<T> vs Dictionary<T> is more important than I first realized. My test removed ActiveReports from the scenario since my focus is on Linq & performance here.


The first test is to replicate the conditions from tiredblogger's post. First I created some really simple sample data:


private void CreateSampleData()
{
 for (var i = 0; i < indicatorCount; i++)
 {
  _indicators.Add(new Indicator(i));
 }

 for (var i = 0; i < indicatorCount; i = i + 2)
 {
  _controlsSimpleList.Add(new ARControl(i));
 }
 _controlsQueryable = _controlsSimpleList.AsQueryable();
}
Then the test simulating what tiredblogger described which uses the IQueryable<Label> as the source of data used with SingleOrDefault:
private void WithLinqQueryable()
{
 var foundCount = 0;
 foreach (var indicator in _indicators)
 {
  var indicatorHeader = string.Format("i{0}", indicator.Id);
  var indicatorControl = _controlsQueryable.SingleOrDefault(x => x.Name == indicatorHeader);
  if (indicatorControl != null)
  {
   foundCount++;
   indicatorControl.Text = IsSpanish
    ? indicator.SpanishText
    : indicator.EnglishText;
  }
 }
 if (foundCount != indicatorCount/2)
  throw new InvalidOperationException("invalid foundCount");
}

I ran a test that uses 400 "indicators" with half of the SingleOrDefault calls not finding a corresponding Label (i.e. returned null). Running the above test in a 10 iteration loop gives me the result of 17046 milliseconds. Next, I realized that IQueryable<T> is not necessary since SingleOrDefault is available as an extension method for both IQueryable<T> (via System.Linq.Queryable.SingleOrDefault) and IEnumerable<T> (via System.Linq.Enumerable.SingleOrDefault). In the prior example, we're using the System.Linq.Queryable.SingleOrDefault implementation. In the next example we'll use the implementation from System.Linq.Enumerable since the source is _controlsSimpleList and it is merely List<T> (i.e. IEnumerable<T> ):
private void WithLinqExtensionMethods()
{
 var foundCount = 0;
 foreach (var indicator in _indicators)
 {
  var indicatorHeader = string.Format("i{0}", indicator.Id);
  var indicatorControl = _controlsSimpleList.SingleOrDefault(x => x.Name == indicatorHeader);
  if (indicatorControl != null)
  {
   foundCount++;
   indicatorControl.Text = IsSpanish
    ? indicator.SpanishText
    : indicator.EnglishText;
  }
 }
 if (foundCount != indicatorCount / 2)
  throw new InvalidOperationException("invalid foundCount");
}

Under the same conditions this one runs in a shocking 46 milliseconds! MUCH faster. Next I thought I'd compare the result to not using any Linq-related technologies at all, just a boring old Dictionary:

private void NoLinqTest()
{
 var controlLookup = new Dictionary();
 _controlsSimpleList.ForEach(x => controlLookup[x.Name] = x);

 var foundCount = 0;
 foreach (var indicator in _indicators)
 {
  var indicatorHeader = string.Format("i{0}", indicator.Id);
  Label indicatorControl;
  if (controlLookup.TryGetValue(indicatorHeader, out indicatorControl))
  {
   foundCount++;
   indicatorControl.Text = IsSpanish
    ? indicator.SpanishText
    : indicator.EnglishText;
  }
 }
 if (foundCount != indicatorCount/2)
  throw new InvalidOperationException("invalid foundCount");
}

This one runs under the same conditions in only 15 milliseconds.

So the saying goes, "When the only tool you have is a hammer, everything looks like a nail." Linq is another nice tool, but it's not the only tool we have :)


For those of you that want to play around with it, you can download the code here.

July 25, 2008

Facts about Russia (2)

Following up on my first post of Russian facts. Here are some more facts...




  • The "current account balance" (as defined by CIA W.F.B.) of the United States is $-738,600,000,000 with a ranking of 164th in the world (last). [1]
  • The "current account balance" of the Russian Federation is $76,600,000,000 with a ranking of 5th in the world. [1]
  • Russia has the world's greatest reserves of mineral and energy resources. [2]
  • Russia produces one-fifth of the worlds diamonds. [7]
  • There was 418,500 American casualties in World War 2 (0.32% of the total population). [5]
  • There was 23,100,000 Soviet Union Casualties in World War 2 (13.7% of the total population). [5]
  • My fiancé's grandfather told us that of his generation, only 1 in 100 Russians (or Soviets?) survived World War II. We made a toast to him as a survivor.
  • The literacy rate in Russia is 99.4%. [6]
  • The literacy rate in the United States is 99.0. [6]
  • Russia has more post-secondary education graduates than any other country in Europe. [3]
  • Moscow Russia is the most expensive city to live in the world. [8]
  • Russia is in the process of building the Russia Tower in Moscow which, upon completion, will be the tallest building in Europe and the second tallest in the World. [9]
  • There are more billionaires living in Moscow Russia than any other city in the world. [4]
  • Only America has more billionaires than Russia (469 vs. 87). [4]

  • 1 http://en.wikipedia.org/wiki/Russian_language
  • 2 http://en.wikipedia.org/wiki/Russia
  • 3 https://www.cia.gov/library/publications/the-world-factbook/rankorder/2187rank.html
  • 4 http://en.wikipedia.org/wiki/List_of_countries_by_population
  • 5 http://en.wikipedia.org/wiki/List_of_countries_by_literacy_rate
  • 6 http://en.wikipedia.org/wiki/Diamond
  • 7 http://en.wikipedia.org/wiki/Moscow
  • 8 http://en.wikipedia.org/wiki/Russia_Tower
  • 9 http://en.wikipedia.org/wiki/List_of_Russian_billionaires

July 22, 2008

Facts about Russia (1)

In total now, I decided I've spent at least one year living in Russia in spans anywhere from a few weeks through going on three months now. As you might expect, after being so close to a country, I've read and learned a thing here and there that I thought might be interesting to share. I'm choosing facts I would have probably not have known had it not been for my personal interest in Russia. I hope and expect at least a couple of my fellow American comrades to find a thing or two listed here interesting.

  • The actual country name is Russian Federation. [2]
  • Russia is the largest country in the world by land mass (by far). [1]
  • Russia occupies nearly twice as much land area (17,098,242 km2 vs 9,629,091 km2) as the USA and has about half of the population (142m vs ~300m). [1]
  • Russia Occupies 11.5% of world's land area.  [1]
  • The next closest is Canada with 6.7%. [1]
  • The population of Russia is 142 million. [3], [5]
  • The Russian language is the largest native language in Europe. [6]
  • Russian scientist Dmitri Ivanovich Mendeleev (Дмитрий Иванович Менделеев) created the periodic table of the elements. [4]
  • Most Russian's (even university graduates) won't know what a "Periodic Table of the Elements" is. They refer to it only as it's official name: "Mendeleev's Table".
  • Some of my colleagues were shocked (and maybe a bit offended) that we were not taught it as "Mendeleev's Table".

  • 1 http://en.wikipedia.org/wiki/List_of_countries_and_outlying_territories_by_total_area
  • 2 http://en.wikipedia.org/wiki/Russia
  • 3 http://en.wikipedia.org/wiki/Dmitri_Mendeleev
  • 4 http://en.wikipedia.org/wiki/World_War_II_casualties
  • 5 http://en.wikipedia.org/wiki/Education_in_Russia
  • 6 http://en.wikipedia.org/wiki/Russian_language

I'll post a more in the next couple days.