Skip to content

Samsung SCH-i760 Windows Mobile Phone Now On Verizon Wireless Web Site

The i760 is now available for order through Verizon Wireless web site. The retail price is $519 but if you can take advantage of various discounts (New Every 2, 2-year contract, data plan), the price will go down to $99.

Samsung Windows Mobile 6 Phone SCH-i760 on Verizon Wireless

The SCH-i760 is a Windows Mobile Pro (Pocket PC) 6 phone, featuring a backlit QWERTY keyboard, 1.3 Megapixel camera/camcorder, microSD, WIFI, and bluetooth.

I still have a few more months to go before my New Every 2 discount will kick in :-(.

Samsung SCH-i760

Related Posts

Finds of the Week – 10/17/2007

As an attempt to make this blog appears more busy:-), I will begin my "Finds of the Week" series. Each week, I will share miscellaneous finds and thoughts I ran into that are related to mostly .NET development.

Here are the finds for this week:

.NET

  • Parallel Performance: Optimize Managed Code For Multi-Core Machines; by Daan Leijen and Judd Hall; via MSDN Magazine. In a few years' time, I predict that most new PCs will be multi-core. This article talks about the new Task Parallel Library (TPL) and provides code samples.
  • document.f.q.focus(); The Billion Dollar Line of JavaScript (by gst, via blogstorm.co.ok) talks about how many people use the Search Box on their browser to navigate to various web sites, instead of typing in a URL, and how this practice translates into revenue for Google. Interesting read.
  • alessandro pointed out that and IMG element with an empty src attribute will call the browser to make a request to the default document (usually default.aspx).
  • Understanding Windows Workflow Foundation (by razi bin rais, via Codeproject.com) is a nice overview of Windows Workflow Foundation.
  • Where are the basic controls in Silverlight 1.1? When I started experimenting with Silverlight recently (see my Silverlight Hello World application), the first question that came to my mind was: where are all the basic controls such as button, checkbox, textbox, etc?

    XAML Intellisense drop-down

    Don't worry! Apparently, they are not there because it's still an Alpha release. According to this post from Tim Sneath, the following controls are planned to be included in the released version of 1.1: Button, TextBox, Scrollbar, Slider, ListBox, CheckBox, RadioButton, ComboBox, and UserControl (no TreeView, RichTextBox, or DataGrid).

 

Tools

  • Probably old news to most CSS pros, but just in case you have not heard, FireBug is a very useful extension for FireFox/CSS development. Highly recommended if you ever work with CSS. I could have saved countless hours debugging HTML/CSS issues with this tool.
  • Notepad++ is a new addition to my toolset. Supports syntax highlighting, regular expression search/replace, Unicode, Macros, and is light-weight.

Windows Mobile / Pocket PC

Blogs

Miscellaneous

  • I am pretty bad with keeping in touch with people, and I have found that LinkedIn makes it fairly easy to keep in touch with past colleages. Last week I had some free time so I decided to look up old colleagues on LinkedIn. It was great to hear from many people I worked with years ago. I found many people by simply searching on the name of the company we worked for.

And Now, Something Different

Check out the Windows Live Maps Bird's Eye view below. See the black car entering the cul-de-sac? That's me and my car.

Microsoft Windows Live Maps - Chinh's Car

How do I know that’s my car? Well, for one thing, my car is black. But the real reason I know it’s me is that a moment later, my garage door opened half-way… as I was about to drive into the garage:

Microsoft Windows Live Maps - Chinh's Car

At first glance, it seems to be an amazing coincidence (like one-in-a-million amazing). What is the chance that Microsoft’s Bird’s Eye low flying plane would fly across my house and snap pictures just as I am about drive into my garage? However, after further calculations, it turns out that the real probability is around 1/8640 (5-second window over 43200 average seconds of day-light). Still a very small chance, but certainly not lottery-winning “amazing”.

My Silverlight 1.1 Hello World Application

Update 1/27/2009: I posted an updated version of this article targeted for Silverlight Runtime 2.0 here

Imagine being able to author rich Internet applications in your .NET language of choice, without having to mess with Javascript, cross-browser compatibility issues, or ActionScript. That’s the promise of Microsoft Silverlight 1.1. In this article, I will document my attempt at creating a Silverlight 1.1 “Hello World” application. My Hello World application is a little bit more fancy than the typical one… this one involves some animation, and drawing a few shapes from code.

Silverlight Hello

If you are new to Silverlight, Silverlight 1.1 (currently in Alpha) is the version that will include the .NET CLR and allow you to write Silverlight code with .NET languages such as C#.

Most Silverlight 1.1 C# examples I found on the web use the XAML file to declare and set object properties. In my example, I am going to create and draw most objects from the code behind c# class.

Installing Visual Studio 2008

If you don’t have Visual Studio 2008 already installed. You can download it from here. Downloading and installing Visual Studio 2008 to my Virtual PC took about 3 hours (1 for the download and 2 for the install).

Note: It’s possible to
develop Silverlight 1.1 applications with Visual Studio 2005
, but the process is not integrated as with Visual Studio 2008

Installing Silverlight Runtimes and Tools

Install the following runtimes and tools from here. I am linking to the main page instead of the individual downloads just in case the download links change.

  • Microsoft Silverlight 1.0 Runtime.
  • Microsoft Silverlight 1.1 Alpha September Refresh
  • Microsoft Silverlight Tools Alpha Refresh for Visual Studio 2008 Beta 2 (July 2007)

Create a New Silverlight Project

  • In Visual Studio, choose File/New/Project and select Visual C#/Silverlight/Silverlight Project. The Silverlight project type is added when you install the Microsoft Silverlight Tools above.
  • Give your project a name.

Creating a new Silverlight Project

Silverlight Project Files

After the project has been created, you are presented with the default Page.xaml file:

Page.xaml

Your Solution should now have the following files:

Page.xaml

The two files that you will be working with are Page.xaml and TestPage.html. Page.xaml stores the markup for the design elements (for more info on XAML, see this MSDN article). TestPage.html is the regular HTML page that will host the main Silverlight object. Silverlight.js is the Javascript helper file for Silverlight applications.

For our example, we will be adding code to Page.xaml.cs. This is what Page.xaml.cs looks like initially:

Page.xaml

Add Some Code

Ready to write some code (complete source code at the end of the article)? First, we are going to add a Storyboard element to our Page.xaml. This Storyboard element serves as a timer for the animation we are going to display.

<Canvas.Resources
 class="kwrd">>
    <Storyboard x:Name
        class="kwrd">="mainTimer" Duration="00:00:00"
            class="kwrd">/>
</Canvas.Resources>

Then, we add some code to the Page.xaml.cs file (click here

for simple “Hello World” version… if you just want a simple Hello World app):

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;

namespace CdoHelloWorld
{
    public partial class Page : Canvas
    {
        /// <summary>Represents a cell on the grid</summary>
        private class Cell
        {
            public double X; //
                x-coordinate of cell
            public double Y; //
                y-coordinate
            public bool On; //
                True if cell is "on"
            public double Order; //
                Display order
        }

        private List<Cell> cells = new List<Cell>(); 
            class="rem">// list of all cells
        private int xSize = 26; 
            class="rem">// width of the grid, in number of cells
        private int ySize = 7; 
            class="rem">// height of the grid
        private int numCells; //
            total number of cells
        private int cellIdx = 0;

        public void Page_Loaded(
            class="kwrd">object o, EventArgs e)
        {
            // Required to initialize variables
            InitializeComponent();

            // Assign a random value to each cell 
            Random rnd = new Random(Environment.TickCount);
            numCells = (int)(xSize * ySize);

            for (int y = 0; y < ySize; y++)
            {
                for (int x = 0; x < xSize; x++)
                {
                    Cell cell = new Cell();
                    cell.X = x * (this.Width / xSize);
                    cell.Y = y * (this.Height / ySize);
                    cell.Order = rnd.NextDouble();
                    cells.Add(cell);
                }
            }

            string template = " "
                            + " x x xxxx x x xx "
                            + " x x x x x x x "
                            + " xxxx xxxx x x x x "
                            + " x x x x x x x "
                            + " x x xxxx xxxx xxxx xx "
                            + " ";

            for (int i = 0; i < template.Length; i++)
            {
                if (template[i] == 'x')
                {
                    cells[i].On = true;
                }
                else
                {
                    cells[i].On = false;
                }
            }

            // Sort the cells by the random values
            cells.Sort(
                delegate(Cell c0, Cell c1)
                {
                    return c0.Order.CompareTo(c1.Order);
                }
            );

            mainTimer.Completed += new EventHandler(mainTimer_Completed);
            mainTimer.Begin();
        }

        void mainTimer_Completed(object sender, EventArgs e)
        {
            // Get the next cell
            Cell cell = cells[cellIdx];

            // Draw the cell
            Rectangle r = new Rectangle();
            r.Stroke = new SolidColorBrush(Colors.DarkGray);
            if (cell.On)
            {
                r.Fill = new SolidColorBrush(Colors.Red);
            }
            else
            {
                r.Fill = new SolidColorBrush(Colors.LightGray);
            }
            r.Width = this.Width / xSize;
            r.Height = this.Height / ySize;
            r.SetValue(Canvas.LeftProperty, cell.X);
            r.SetValue(Canvas.TopProperty, cell.Y);
            Children.Add(r);
            cellIdx++;

            if (cellIdx <= numCells)
            {
                // restart the timer
                mainTimer.Begin();
            }
        }

    }
}

Here’s the simple version of the code:

TextBlock t = new TextBlock();
t.Text = "Hello world!";
Children.Add(t);

Firefox Bug and Workaround

There is a known problem that causes the Silverlight object to not show up in Firefox. To fix the problem, remove the DOCTYPE declaration from the HTML file. See this MSDN forum thread.

Deploying Silverlight Applications to Your Web Server

To deploy my application, I simply copied the files including the ClientBin directory to my web server. Any web server will do (the server that hosts my Hello World application is an apache server).

And Now, Ladies and Gentlements, My Hello World Silverlight App

Click here.

Source Code

Download complete source code for this article.

StringBuilder is not always faster – Part 2 of 2

In a previous article (“StringBuilder is not always faster), I provided some quick benchmark data and gave “rules of thumb” for when to use StringBuilder and when to use traditional string concatenations. In this follow-up article, I will attempt to provide a more detailed analysis.

If you don’t want to bother with the details, jump directly to the conclusions here.

A Look at the Generated MSIL

A reader, Matt, suggested that it’s possible the compiler may have noticed that I never use the generated test objects in my benchmark code and not created them. That would definitely invalidated my test results!

Here’s the original benchmark code:

for (int i = 0; i <= 1000000; i++)
{
    // Concat strings 3 times using StringBuilder
    StringBuilder s = new StringBuilder();
    s.Append(i.ToString());
    s.Append(i.ToString());
    s.Append(i.ToString());
}

And this one, using traditional concatenation, took slightly less time (1344 milliseconds):

for (int i = 0; i <= 1000000; i++)
{
    // Concat strings 3 times using traditional concatenation
    string s = i.ToString();
    s = s + i.ToString();
    s = s + i.ToString();
}

According to Lutz Roeder’s .NET Reflector (great tool), the answer is no. Here’s the IL from Reflector:

.entrypoint
.maxstack 2
.locals init (
    [0] int32 i,
    [1] class [mscorlib]System.Text.StringBuilder s,
    [2] string V_2,
    [3] bool CS$4$0000)
L_0000: nop
L_0001: ldc.i4.0
L_0002: stloc.0
L_0003: br.s L_003b
L_0005: nop
L_0006: newobj instance void [mscorlib]System.Text.StringBuilder::.ctor()
L_000b: stloc.1
L_000c: ldloc.1
L_000d: ldloca.s i
L_000f: call instance string [mscorlib]System.Int32::ToString()
L_0014: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
L_0019: pop
L_001a: ldloc.1
L_001b: ldloca.s i
L_001d: call instance string [mscorlib]System.Int32::ToString()
L_0022: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
L_0027: pop
L_0028: ldloc.1
L_0029: ldloca.s i
L_002b: call instance string [mscorlib]System.Int32::ToString()
L_0030: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
L_0035: pop
L_0036: nop
L_0037: ldloc.0
L_0038: ldc.i4.1
L_0039: add
L_003a: stloc.0
L_003b: ldloc.0
L_003c: ldc.i4 0xf4240
L_0041: cgt
L_0043: ldc.i4.0
L_0044: ceq
L_0046: stloc.3
L_0047: ldloc.3
L_0048: brtrue.s L_0005
L_004a: ldc.i4.0
L_004b: stloc.0
L_004c: br.s L_0078
L_004e: nop
L_004f: ldloca.s i
L_0051: call instance string [mscorlib]System.Int32::ToString()
L_0056: stloc.2
L_0057: ldloc.2
L_0058: ldloca.s i
L_005a: call instance string [mscorlib]System.Int32::ToString()
L_005f: call string [mscorlib]System.String::Concat(string, string)
L_0064: stloc.2
L_0065: ldloc.2
L_0066: ldloca.s i
L_0068: call instance string [mscorlib]System.Int32::ToString()
L_006d: call string [mscorlib]System.String::Concat(string, string)
L_0072: stloc.2
L_0073: nop
L_0074: ldloc.0
L_0075: ldc.i4.1
L_0076: add
L_0077: stloc.0
L_0078: ldloc.0
L_0079: ldc.i4 0xf4240
L_007e: cgt
L_0080: ldc.i4.0
L_0081: ceq
L_0083: stloc.3
L_0084: ldloc.3
L_0085: brtrue.s L_004e
L_0087: ret

Size of Concatenated Values and StringBuilder with Initial Capacity

More questions from Matt: how does the performance curve change if the concatenated values are larger? And what if you seed the StringBuilder object with an initial capacity?

To answer the questions, I wrote some more benchmarks (complete source code at the bottom of this article) to compare three different methods of concatenation:

  • “+” concatenation: This is the traditional a + b + c method.
  • StringBuilder: Create a StringBuilder object using the default constructor and calling Append().
  • StringBuilder/Pre-allocated: Create a StringBuilder object and preallocate the initial capacity so that it does not need to expand later.

String Size = 10

The chart below shows elapsed times (ms) of the three concatenation methods, with the concatenated string size equaled to 10 characters

StringBuilder Benchmark - Elapsed time vs Concatenations - String Size 10

As the chart illustrates, when the size of the concatenated value is small (10 characters in this test), “+” concatenation (blue line) performs faster than StringBuilder until the number of concatenations reaches 6. After 6, StringBuilder starts to work exponentially faster.

However, when compared with the StringBuilder/Pre-allocated method, StringBuilder starts to perform as fast as “+” concatenation much earlier: at 3 concatenations.

Note: The orange line for StringBuilder is not very linear. My guess is that it’s due to the need to allocate space as needed. The memory allocation itself will consume CPU cycles. The default StringBuilder constructor will allowcate 16 bytes initially. Thereafter, it will allocate two times the current capacity whenever needed.

String Size = 100

StringBuilder Benchmark - Elapsed time vs Concatenations - String Size 100

When the concatenated value is 100 characters, the all three methods perform very similarly up to three concatenations, then StringBuilder/Pre-allocated pulls ahead at 4 concatenations.

Concatenated String Size = 1000

StringBuilder Benchmark - Elapsed time vs Concatenations - String Size 1000

At 1000 characters, things begine a little bit more interesting: StringBuilder/Pre-allocated is faster in all cases (although the difference is very small until about 6 concatenations). Since it may not be always possible or practical to know the final string size ahead of time, for this graph, I also added two more series to show what happens if you over-estimate or under-estimate the final capacity. As expected, there is a performance penalty for both. The more inaccurate your estimated capacity is, the higher of a performance penalty you will get.

What about String.Concat?

Lars Wilhelmsen asked “What about string.Concat?” According to my research, string.Concat is basically identical to “+” used on a single line.

This:

string s = "a" + 
                    class="str">"b" + "c";

Is the same (same generated IL) as this:

string s = string.Concat(
 class="str">"a", "b", "c");

But not this:

string s = "a";
s = s + "b";
s = s + "c";

Remember, the “+” must be on the same logical line, otherwise, the compiler will convert each line into a separate string.Concat operation, resulting in slower performance.

AJ has written a post detailing string.Concat here. Thanks, AJ, for pointing it out.

And String.Format?

Flyswat wanted to know about string.Format. I did some quick benchmark code again. The string.Format code below took 58 milliseconds to run 100,000 iterations:

string s = string.Format(
          class="str">"Value: {0}", strVal);

While this code, using “+” concatenation, only took 9 milliseconds (also 100,000 iterations):

string s = "Value: " + strVal;

According to the above numbers, string.Format is significantly slower than “+” concatenations. The difference in speed is similar between s.AppendFormat(“Value: {0}”, strVal) and s.Append(“Value: ” + strVal). I have used String.Format a lot in my code and I have not thought about this performance penalty. It does make sense. String.Format (or StringBuilder.AppendFormat) has to scan the string looking for format specifiers… that takes time. String.Format is very useful to make the code easier to read or when you actually need to format numbers. Even with this new data, I will not neccessarily shy away from using string.Format. I will however definitely be much more observant when using it, especially when used inside a loop or performance critical code path.

Conclusions

The new benchmarks do point to StringBuilder/Pre-allocated as the fastest method regardless of number of concatenations, when the concatenated string value is large (1000 characters).

With that in mind, here are my slightly modified rules of thumbs for string concatenation. Remember, “rules of thumb” are short statements to provide general princicles, and may not be accurate for every single situation. For performance criticial code, you should consider running some benchmarks/profiling yourself.

  • For 1-4 dynamic concatenations, use traditional “+” concatenation.
  • For 5 or more dynamic concatenations, use StringBuilder.
  • When using StringBuilder, try to provide the starting capacity as close to the final string size as possible.
  • When building a big string from several string literals, use either the @ string literal or the + operator.
  • For performance critical code, consider running your own benchmarks

Additional Reading

Notes

The benchmarks in this article were run on a Pentium 4 2.4 GHz CPU, with 2GB of RAM. With .NET framework: 2.0.

Source Code for Benchmarks

Source code here.

kick it on DotNetKicks.com

My New & Improved Samsung i730 Windows Mobile Phone

A few days ago, my old and trusty Samsung SCH-i730 Windows Mobile phone decided to bite the dust. One moment, I pulled it out of my pocket to look at the time and it was dead… just like that. No sound. No display. It was an eerie sight. I tried a soft reset, changed battery, hard reset, nothing.

Luckily, since I had purchased insurance for the phone (the only time I purchased insurance for an electronic gadget), I called Verizon. Two days later, I now have a brand new i730.

Samsung SCH-i730 box

Normally, this would be a none-event. However, something interesting happened: the replacement phone works much better than the one I used to have. Read about the problems I had with the old phone here. On the new phone, everything runs noticeably faster. There is no more unexplained slowness. Audio during phone calls now works as expected with no cut outs.

New Samsung SCH-i730 Windows Mobile Phone

I have two theories on why:

  • I had upgraded my old phone to Windows Mobile 2005 and that version of the Windows Mobile OS was causing problems on the phone
  • I had a defective phone

I will never know for sure the real cause, since the old phone is no more.

Samsung i730 owners out there, if your phone doesn’t seem to work quite right and have the problems described here, either try to downgrade to Windows Mobilde 2003, or if you have not upgraded to WM2005, you just may have a defective device.

Back To Top