Posts RSS Comments RSS 129 Posts and 246 Comments till now

Archive for August, 2007

Sorting Words by Their Length

Don’t ask why I come up with this post :) Let’s just say it has something to do with Regular Expression.

 

The first method that immediately come up to mind (and usually the worst :) ) is as follows:

struct Res
{
   //To Record the Result
   public String words;
   public int wordcount;
}

public static Res WorstWordByLengthSort(string raw)
{
   Res myresult = new Res();
   myresult.wordcount = 0;
   string[] words = raw.Split("n".ToCharArray());
   raw = "";
   foreach (string word in words)
      raw += word + " ";

   words = raw.Split(" ".ToCharArray());
   ArrayList ar = new ArrayList();

   foreach (string word in words)
   {
      string tstr = word.Trim();
      if (tstr == "")
         continue;
      myresult.wordcount++;
      if (ar.Count == 0)
      {
         ar.Add(tstr);
      }
      else
      {
          int count = ar.Count;
          bool inserted = false;
          for (int i = 0; i < count; i++)
          {
              if (ar[i].ToString().Length <= tstr.Length)
              {
                  if (!ar.Contains(tstr))
                  {
                      ar.Insert(i, tstr);
                      inserted = true;
                   }
              }
          }
          if (!inserted && !ar.Contains(tstr))
             ar.Add(tstr);
      }
   }
   StringBuilder sb = new StringBuilder();
   foreach (object o in ar)
       sb.AppendLine(o.ToString());
    myresult.words= sb.ToString();
    return myresult;
}

 

It will work flawlessly (sort of .. :) ), but it will not allow duplication of word. After tinkering for a while, I came up with an idea to improve its performance. A better solution would be to use a dictionary where the length of the word becomes the key. If a key is already exist in the dictionary, we just simply append the word into the value of that particular key. The idea is implemented as follows:

struct Res
{
   //To Record the Result
   public String words;
   public int wordcount;
}

public static Res BetterWordByLengthSort(string raw)
{
   Res myresult = new Res();
   myresult.wordcount = 0;
   myresult.words = "";
   StringBuilder result = new StringBuilder();
   Dictionary myDict = new Dictionary();
   ArrayList keys = new ArrayList();
   string[] words = raw.Split(”n”.ToCharArray());

   raw = “”;
   foreach (string word in words)
   {
      string tword = word.Trim();
      raw += tword + ” “;
   }
   words = null;
   words = raw.Split(” “.ToCharArray());

   foreach (string word in words)
   {
      string tempWord = word.Trim();
      if (tempWord == “”)
         continue;
      int tlength = tempWord.Length;
      if (myDict.ContainsKey(tlength))
      {
         myDict[tlength] = myDict[tlength] + “n” + tempWord;
      }
      else
      {
          keys.Add(tlength);
          myDict.Add(tlength, tempWord);
      }
      myresult.wordcount++;
   }
   //Sort the keys ASC
   keys.Sort();
   for (int i=keys.Count-1; i>=0; i–)
   {
      result.AppendLine(myDict[(int)keys[i]]);
   }
   myresult.words = result.ToString();
   return myresult;
}

I created a GUI project to compare their performance. With same input of 1443 words, the Worst method took 734 ms, while the Better method took only 15 ms. And yes, if you remember your Big O complexity, the Better method is definitely much more efficient compared to the Worst method :)

SQL String Formatter (Part 2)

As I promised before, I will put the output of the programs that I mention in the previous post.

As input I will use the following SQL string (which I have verified that it is a valid SQL statement).

 ALTER PROCEDURE [dbo].[aspnet_Setup_RemoveAllRoleMembers] @name   sysname AS BEGIN     CREATE TABLE #aspnet_RoleMembers     (         Group_name      sysname,         Group_id        smallint,         Users_in_group  sysname,        User_id         smallint     );     INSERT INTO #aspnet_RoleMembers     EXEC sp_helpuser @name;     DECLARE @user_id smallint;    DECLARE @cmd nvarchar(500);    DECLARE c1 cursor FORWARD_ONLY FOR         SELECT User_id FROM #aspnet_RoleMembers;    OPEN c1;    FETCH c1 INTO @user_id;    WHILE (@@fetch_status = 0)    BEGIN        SET @cmd = 'EXEC sp_droprolemember ' + '''' + @name + ''', ''' + USER_NAME(@user_id) + '''';        EXEC (@cmd);        FETCH c1 INTO @user_id      END;     CLOSE c1;    DEALLOCATE c1  END

The output of the program are as follows:

  1. SQLinForm
    ALTER
    PROCEDURE [dbo].[aspnet_Setup_RemoveAllRoleMembers] @name sysname
    AS
            BEGIN
                    CREATE TABLE #aspnet_RoleMembers
                                    (
                                    Group_name sysname    ,
                                    Group_id smallint     ,
                                    Users_in_group sysname,
                                    User_id smallint
                                    );
                    INSERT INTO #aspnet_RoleMembers EXEC sp_helpuser @name;
                    DECLARE @user_id smallint;
                    DECLARE @cmd nvarchar(500);
                    DECLARE c1
                    cursor FORWARD_ONLY FOR
                            SELECT User_id FROM #aspnet_RoleMembers;
                            OPEN c1;
                            FETCH c1 INTO @user_id;
                    WHILE (@@fetch_status = 0)
                    BEGIN
                            SET @cmd =  'EXEC sp_droprolemember ' + '''' + @name + ''', ''' + USER_NAME(@user_id) + '''';
                            EXEC (@cmd);
                            FETCH c1 INTO @user_id
                    END;
                    CLOSE c1;
                    DEALLOCATE c1
            END
    



    Initially I thought there was missing ‘END’, but I found out that because I choose ‘Any SQL’ instead of ‘SQL Server’. Very impressive!!!

  2. SQL Online Formatter
    ALTER PROCEDURE [DBO].[ASPNET_SETUP_REMOVEALLROLEMEMBERS]
                   @name SYSNAME
    AS
      BEGIN
        CREATE TABLE #ASPNET_ROLEMEMBERS (
          GROUP_NAME     SYSNAME,
          GROUP_ID       SMALLINT,
          USERS_IN_GROUP SYSNAME,
          USER_ID        SMALLINT);
    
        INSERT INTO #ASPNET_ROLEMEMBERS
        EXEC SP_HELPUSER
           @name;
    
        DECLARE  @user_id SMALLINT;
    
        DECLARE  @cmd NVARCHAR(500);
    
        DECLARE C1 CURSOR FORWARD_ONLY FOR
        SELECT USER_ID
        FROM   #ASPNET_ROLEMEMBERS;
    
        OPEN C1;
    
        FETCH  C1
        INTO @user_id;
    
        WHILE (@@FETCH_STATUS = 0)
          BEGIN
            SET @cmd = 'EXEC sp_droprolemember ' + '''' + @name + ''', ''' + USER_NAME(@user_id) + '''';
    
            EXEC( @cmd);
    
            FETCH  C1
            INTO @user_id
          END;
    
        CLOSE C1;
    
        DEALLOCATE C1
      END
    

    As you see, it also performs as good as SQLinForm

  3. SQL Review
    ALTER PROCEDURE [dbo].[aspnet_Setup_RemoveAllRoleMembers] @name sysname AS
    BEGIN
    
    CREATE TABLE #aspnet_RoleMembers (
          Group_name sysname,
          Group_id smallint,
          Users_in_group sysname,
          User_id smallint
       );
    
    INSERT INTO #aspnet_RoleMembers
    EXEC sp_helpuser @name;
    
    DECLARE
       @user_id smallint;
    
    DECLARE
       @cmd nvarchar(500);
    
    DECLARE
       c1
    CURSOR FORWARD_ONLY
    FOR
    SELECT
       User_id
    FROM
       #aspnet_RoleMembers;
       OPEN c1;
       FETCH c1 INTO @user_id;
       WHILE (@@fetch_status = 0)
    BEGIN
    
    SET @cmd = 'EXEC sp_droprolemember ' + '''' + @name + ''', ''' + USER_NAME(@user_id) + '''';
    
    EXEC (@cmd);
       FETCH c1 INTO @user_id
    END;
    CLOSE c1;
    DEALLOCATE c1
    END
    


    Unfortunately there is no option to indent text between BEGIN and END. But the plus point is you can run it

  4. Pl/sql tidy
    Hmm.. doesn’t seem to work. Is it because it only parse PL/SQL? (I will investigate further when I really have nothing to do :P)

As for the LEX script, I’m still trying to get it work on C# using CsLEX, so it would take sometime before I post the result here.

Since When MyBlogLog supports more than 300 contacts?

Once in a while, I log in to MyBlogLog (It’s the social network site for bloggers). In my profile, I put “Sticks and stones love, I saved your life and you saved mine, we’re square” … oops .. :P … I mean “If you add me, I will add you”, or something like that …

 

After quite sometime my list of contacts grows until 299. I have around 5 people that have added me to their contact, but MyBlogLog didn’t allow me to return the favour by adding them into my contact. I forgot when exactly this thing happened, maybe roughly 2-3 months ago? After trying for 1 or two days, I stopped trying.

 

So today I login again to MyBlogLog and found there are 35 people who have added me. Without any intention or expectation, I clicked the add to contact button.. Whoa.. I can now add more people into my contact list. Since when did this happen?

 

To all MyBlogLog-gers, I offer you my humble apology for not keeping my word of adding you into my contact list. I will definitely return the favour.

SQL String Formatter (Part 1)

I am looking for a code (or command line software) that able to format/tidy-up SQL string to make it readable and doesn’t irritate the eyes. So far I have found:

  1. SQLinForm
    It’s quite handy, you can run it on your browser and download the offline version which is packaged into one single Java Jar file. Unfortunately, I’m looking for something with with command line or open source. At least with command line support I can invoke it from my .NET program to process the temporary file.
  2. SQL Online Formatter
    Still without the programmability support.
  3. SQL Review
    With command line support. Unfortunately It’s throwing error on one of my stored procedure, but it still gives you the output.
  4. Pl/Sql Tidy
    This program is only available in command line. Unfortunately, it never able to process my stored procedure. I not so sure whether it’s still maintained.
  5. Using Flex Script.
    This page is pure inspirational. It immediately opened up my eyes for the possibility of using Flex or Regular Expression. I think will stick to this solution.

Although I have made up my mind, I will provide the output of each program in the next posting. Hopefully once I am be able to port VS. Babu’s lex script (or make my own regular expression code), I will share it with you all.

Credits:

1. Carson McDonald

Apparently no Optimization is needed for DataTable.Select()

Almost losing sleep because of my colleague’s question, I posted the question in .NET Groups where I frequently hang out.

 

One contributor suggested me to use DataTable.Rows.Find(), especially when we are searching by the Index column of that DataTable. I never heard of this, so I keep it noted as an additional advise to my colleague.

 

After much thinking, I somehow became doubting that DataTable.Select() is the actual source of the bottleneck. So this morning I asked her to run the profiler to check the performance of her program. The profiler’s result proven my doubt. The bottleneck was caused by multiple calling of Web Services.

 

All this time I already have a little discomfort with Web Service. I thought the overhead of transmitting data by text XML is too much, especially when you have thousands of records transmitted at an instance. So I spent a little time to googling for opinions that against Web Service (Web Service here refers to those web services that commonly implemented using SOAP). Eventually, I stumbled to this page. I highly recommend it. It’s funny, it’s witty and you might want to use it as an argument when debating against SOAP proponents :)

 

Talking about Profiler, she is using ANTS Profiler. It’s not free :) But you could download the 14-days trial. And of course you can always ask Google for a help.

Pages (2): [1] 2 »

Close
E-mail It
Socialized through Gregarious 42