About the author

Miron Abramson
Me
Software Engineer, Senior Developer at Rima, and .NET addicted for long time.

Recent comments

Authors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008

Creative Commons License

Blog Flux Directory
Technology Blogs - Blog Top Sites

High performance css minifier

It is known that minifying the JavaScript and CSS files can really reduce the files size and improve the general site performance. Lot of sites (BlogEngine.NET among them)  do it on run-time and not it the build time. At this point, I want to recommend the JavaScript minifier JSMIN by Douglas Crockford. It does the job very good, and by far, much faster than all the RegularExpression \ Replace minifiers. Because in my Compression project MbCompression I do the minifying on run-time, I decided to use jsmin minifier.

The Css minifier

All the Css minifiers I found are using Regular Expression\ Replace to remove the unneeded characters. This is working fine, but have a realy bad performance, special on run-time. The speed is slow (special using the Regular Expression), and another important thing is, every Replace creates a very big string in the memory! (Strings are immutable, remember?), so if you have several Replaces, it creates several big strings in the server memory!

To improve performance, I took  JSMIN idea, that are not using any strings in the memory, and perform the minifying much faster, and created a CSS minifier that produce a small CSS file, much faster, and with much less memory overhead.

This minifier was tested on several CSS files. Feel free to download it and use it. If there is any file that not been minify correctly, send it to me, and I will try to improve the minifier.

CssMinifier.cs (9.59 kb)

Currently rated 5.0 by 5 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: C# | Client side | Performance
Posted by Miron on Sunday, June 29, 2008 4:48 AM
Permalink | Comments (5) | Post RSSRSS comment feed

Create your own new Type and use it on run-time (C#)

It is not something you will use on daily bases. It doesn't have good performance. But one day, you will have to use it so it's good to know that it is possible. As you can understand from the title, I'm talking about creating a new type with fields and properties (it can also have methods), create instance/s from it and use it. It will not be 'type safe', of course, and you will be able to use it - read and set its values only with reflection. but, all the DataBindingControls (GridView, FormView etc...) are binding the data using reflection, so they will be happy to bind and use your new created objects from your own type you created on run-time.

Lets cut the crap and jump into the code:

Let's say you got an xml from a webservice. and you want to create an object from it. Something like that:

You receive an xml like this:

<root>
    <column name="Name">Miron</column>
    <column name="LastName">Abramson</column>
    <column name="Blog">www.blog.mironabramson.com</column>
</root> 

You want to make a 'match' type that looks like this:

public class MyType
{
    public string Name{ get; set; }
    public string LastName{ get; set; }
    public string Blog{ get; set; }
}

and than create an object from that type and fill it with your data. The prolem is that you don't know what will be the values of the xml attributes and fields. So you need to create the object on run-time:

private object CreateOurNewObject()
{
    string _xml = "<root>" +
        "<column name=\"Name\">Miron</column>" +
        "<column name=\"LastName\">Abramson</column>" +
        "<column name=\"Blog\">www.blog.mironabramson.com</column>" +
        "</root>";

    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(_xml);

    // create a dynamic assembly and module
    AssemblyName assemblyName = new AssemblyName();
    assemblyName.Name = "tmpAssembly";
    AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
    ModuleBuilder module = assemblyBuilder.DefineDynamicModule("tmpModule");

    // create a new type builder
    TypeBuilder typeBuilder = module.DefineType("BindableRowCellCollection", TypeAttributes.Public | TypeAttributes.Class);

    // Loop over the attributes that will be used as the properties names in out new type
    foreach (XmlNode node in xmlDoc.SelectSingleNode("root").ChildNodes)
    {
        string propertyName = node.Attributes["name"].Value;

        // Generate a private field
        FieldBuilder field = typeBuilder.DefineField("_" + propertyName, typeof(string), FieldAttributes.Private);
        // Generate a public property
        PropertyBuilder property =
            typeBuilder.DefineProperty(propertyName,
                             PropertyAttributes.None,
                             typeof(string),
                             new Type[] { typeof(string) });

        // The property set and property get methods require a special set of attributes:

        MethodAttributes GetSetAttr =
            MethodAttributes.Public |
            MethodAttributes.HideBySig;

        // Define the "get" accessor method for current private field.
        MethodBuilder currGetPropMthdBldr =
            typeBuilder.DefineMethod("get_value",
                                       GetSetAttr,
                                       typeof(string),
                                       Type.EmptyTypes);

        // Intermediate Language stuff...
        ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator();
        currGetIL.Emit(OpCodes.Ldarg_0);
        currGetIL.Emit(OpCodes.Ldfld, field);
        currGetIL.Emit(OpCodes.Ret);

        // Define the "set" accessor method for current private field.
        MethodBuilder currSetPropMthdBldr =
            typeBuilder.DefineMethod("set_value",
                                       GetSetAttr,
                                       null,
                                       new Type[] { typeof(string) });

        // Again some Intermediate Language stuff...
        ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator();
        currSetIL.Emit(OpCodes.Ldarg_0);
        currSetIL.Emit(OpCodes.Ldarg_1);
        currSetIL.Emit(OpCodes.Stfld, field);
        currSetIL.Emit(OpCodes.Ret);

        // Last, we must map the two methods created above to our PropertyBuilder to
        // their corresponding behaviors, "get" and "set" respectively.
        property.SetGetMethod(currGetPropMthdBldr);
        property.SetSetMethod(currSetPropMthdBldr);
    }

    // Generate our type
    Type generetedType = typeBuilder.CreateType();

    // Now we have our type. Let's create an instance from it:
    object generetedObject = Activator.CreateInstance(generetedType);

    // Loop over all the generated properties, and assign the values from our XML:
    PropertyInfo[] properties = generetedType.GetProperties();

    int propertiesCounter = 0;

    // Loop over the values that we will assign to the properties
    foreach (XmlNode node in xmlDoc.SelectSingleNode("root").ChildNodes)
    {
        string value = node.InnerText;
        properties[propertiesCounter].SetValue(generetedObject, value, null);
        propertiesCounter++;
    }
  
    //Yoopy ! Return our new genereted object.
    return generetedObject;
}

Mazal Tov!!!

We create our type and instance from it on run-time !!!

In the file bellow, there is full working exmple of the code

 

MyTypeRunTime.zip (4.15 kb)

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by Miron on Monday, June 09, 2008 10:43 AM
Permalink | Comments (1) | Post RSSRSS comment feed

Sorting a collection using Linq and 'SortExpression' string

Already happened to you that you had a collection of object from type 'X' with some properties, and you had to sort it one time by property 'ID', and another time by property 'Name' ? You wished that you can sort it by just using a 'Sort Expression' ? If still not, I'm sure this moment will arrive sooner or later. Let me save you some time and an headache.

This is how it can be done: 

 public static IEnumerable<T> Sort<T>(this IEnumerable<T> source, string sortExpression)
{
    string[] sortParts = sortExpression.Split(' ');
    var param = Expression.Parameter(typeof(T), string.Empty);
    try
    {
        var property = Expression.Property(param, sortParts[0]);
        var sortLambda = Expression.Lambda<Func<T, object>>(Expression.Convert(property, typeof(object)), param);

        if (sortParts.Length > 1 && sortParts[1].Equals("desc", StringComparison.OrdinalIgnoreCase))
        {
            return source.AsQueryable<T>().OrderByDescending<T, object>(sortLambda);
        }
        return source.AsQueryable<T>().OrderBy<T, object>(sortLambda);
    }
    catch (ArgumentException)
    {
        return source;
    }
}

Just drop it in a static class, and you will be able to sort any collection that implement the interface IEnumerable.

Lets say you have a class 'User':

public class User
{
    public int ID { get; set; }
    public string Name { get; set; }
}

and a List<User> collection: users. You can sort it however you want:

IEnumerable<User> sortedUsersIEnumerable = users.Sort<User>("ID desc"); 

Or

List<User> sortedUsersList = users.Sort<User>("Name").ToList();

I really think this extension should be 'built-in' part of the 'Linq'. 

Extensions.cs (1.08 kb)

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: ASP.NET | C# | Server side
Posted by Miron on Wednesday, May 07, 2008 1:59 PM
Permalink | Comments (1) | Post RSSRSS comment feed

Uniform Distribution algorithm in C#

Background
Where I work, one of the serviced we give to our clients is Medical articles.With the time, we have tones of articles. Millions. All PDF files, and all are in the same folder.

The Problem
It became impossible to open the folder with Windows explorer, trying to search, copy or move files. I had to find a way to reorder it, and divide it into 1000 folders that every folder will have around the same number of files, and when a request for a specific file will come, I will be able to know in witch folder it is.

The Solution 
I contacted my brother Ari (his site is outdated) for help. He have PhD from the "Electrical Engineering department" at the Technion institute.  He is the smartest guy I have known. So, that is his Algorithm, I just implemented it in C#. It's not too complicate, but it does the job perfect.

The algorithm gets a string and maps it into the set 0-999 (or any given range) with uniform distribution.

/// <summary>
/// Get the position in the range of the specified string
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public int GetPosition(string input)
{
    if (string.IsNullOrEmpty(input))
    {
        return 0;
    }

    input = hasher.ComputeHash(input).Replace("-",string.Empty);
    double Sum = 0.0;
    int Aj;
    double Tj;
    double Pj;

    for (int j = 0; j < input.Length; j++)
    {
        Aj = (int)input[j];
        Tj = (Math.PI * (1 + j%5) / 2);
        Pj = Math.Pow(Aj,Tj);
        Sum += Math.Round((Math.Ceiling(Pj) - Pj) * Range) * Tj;
    }
    return ((int)(Sum % Range)) + LowerValue;
}

To use it, just create an object from type Mapper, and call the 'GetPosition' method for any needed string:

Mapper aMap = new Mapper(RANGE);
int position = aMap .GetPosition(input)); 

The Results 

I run the algorithm few times with random strings 10 chars long and map them into some ranges of 'folders'. Here are the results:

1,000,000 random strings into range of 1000: the folder with the maximum # of files contained 1156 files, and the minimum  contained 886 files.
1,000,000 random strings into range of 100: the folder with the maximum # of files contained 10,699 files, and the minimum  contained 8800 files.
1,000,000 random strings into range of 10: the folder with the maximum # of files contained 106,873 files, and the minimum  contained 98,747 files.

Very nice results. Maybe not perfect, but certainly good enough for this kind of purpose!

Special thanks to my brother Ari for his help.

Source code:

AriMap.zip (2.34 kb)

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: C#
Posted by Miron on Wednesday, April 02, 2008 8:58 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Extensions can make us free from testing against null

The concept of the Extensions in the last frameworks is great. They are extremely easy to write and use, give us infinit options to add needed methods we just wished to have in the framework,  and the thing that most catched my eyes is the fact that the extensions are "attached" to an instance of an object, but can be excute with a 'null' object. It is kind of weird.

Excuting the following code will thow an exception (of course):

string s;
s = null;
s = s.Replace("bla", "alb");

But, if we add the following extension:

public static string EReplace(this string s, string oldValue, string newValue,
    bool ignoreCase)
{
    if (s == null)
        return s;

    if (ignoreCase)
    {
         return Regex.Replace(s, oldValue, newValue, RegexOptions.IgnoreCase);
    }
    return s.Replace(oldValue, newValue);

 and try to excute the code:

string s;
s = null;
s = s.EReplace("bla", "alb",true);

the code will run without any exception.

Conclusion:

Using extensions and validate input, will make us free from testing against null any object before excuting a method, and this way, avoid errors that can be throw exceptions on runtime environment.

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: C#
Posted by Miron on Saturday, March 22, 2008 5:32 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Another version for the missing method: Enum.TryParse (in C#)

The 'TryParse' methods for all types are very useful and I'm using them all the time. It's very surprising that Microsoft didn't include in the Framework a method that can be very useful: Enum.TryParse. A lot of coders find themself writing from time to time  'parsing' methods for their enums. Something like that:

public enum ImageType
{
    Jpg,
    Gif,
    Png
}

public static ImageType ParseImagetype(string typeName)
{
    typeName = typeName.ToLower();
    switch (typeName)
    {
        case "Gif":
            return ImageType.Gif;
        case "png":
            return ImageType.Png;
        default:
        case "jpg":
            return ImageType.Jpg;
    }
}...

 Thats work fine, but you need to write such 'parsing' method for each enum you have.  The Enum class have it's own 'parsing' method (that luckly have 'IgnoreCase' flag), but not a TryParse method. The commonly fix around is to put the Enum.Parse method inside Try & Catch, what is, of cource, give bad performance in case of failure. The Enum class have also a method 'IsDefined' that return an indication if a value is exists in the enum. unfortunately, this method doesn't have an  'IgnoreCase' flag.

So, trying to put all this 'knowledge' together, I wrote my own generic version for 'Enum.TryParse' method that is also ignore case and not using try & catch:

public static bool EnumTryParse<T>(string strType,out T result)
{
    string strTypeFixed = strType.Replace(' ', '_');
    if (Enum.IsDefined(typeof(T), strTypeFixed))
    {
        result = (T)Enum.Parse(typeof(T), strTypeFixed, true);
        return true;
    }
    else
    {
        foreach (string value in Enum.GetNames(typeof(T)))
        {
            if (value.Equals(strTypeFixed, StringComparison.OrdinalIgnoreCase))
            {
                result = (T)Enum.Parse(typeof(T), value);
                return true;
            }
        }
        result = default(T);
        return false;
    }
}

The line 'string strTypeFixed = strType.Replace(' ', '_');' is because I was getting the data from third party WebService that send the enum strings with spaces, what is not allowed in enum, so my enums had '_' instead of  spaces.

To parse a ImageType (from the example above) just use it like this:

ImageType type;
if (Utils.EnumTryParse<ImageType>(typeName, out type))
{
    return type;
}
return ImageType.Jpg;

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:
Categories: C#
Posted by Miron on Saturday, March 08, 2008 8:54 AM
Permalink | Comments (8) | Post RSSRSS comment feed

Update to my compression module to compress third party scripts

My last version of the compression module was working great and able to compress and cache pages, WebResources, CSS and JavaScripts files. It have one problem (that similiar to most of the compression modules you can find). To compress the javascripts files, you have to modify the way you register them and change their links to something like that: 

<script type="text/javascript" src="/Scripts/utils.js">

needs to became 

<script type="text/javascript" src="Scripts/jslib.axd?d=~/Scripts/utils.js">

It is not so hard work to do, but it became useless when you use third party controls as 'Telerik' (RadControls)  and force it to doesn't use it's scripts as WebResources. In such case, the controls 'Injects' their scripts links into the HTML code and you can't modify them as needed to let the compression handler to compress it.  In the new version of my compression component, I added a ResponseFilter that parse the Scripts links in the HTML and convert them into 'compressable' links. By default, this option is disabled in the compression module. To enable it (if you use such third party controls), just add the attribute compressThirdParityScripts="true" to the compression configuration.

Full implementation instructions can be found here: Compression module implementation 

Latest code can be downloaded from: http://www.codeplex.com/MbCompression

Currently rated 4.7 by 3 people

  • Currently 4.666667/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by Miron on Friday, February 22, 2008 4:15 AM
Permalink | Comments (3) | Post RSSRSS comment feed

Simple Generic Business Entities

"Business Entites" are widly commonly use everywhere. Sometimes the entities are very big and contains a lot of methods and properties, but most of the time, they are basicly objects that holds data in easier and cleaner way than DataTables/DataSets. Sometimes you have entity for specific type such "Customer", "Laboratory", "Shop" or whatever, but lots of time you just need to load and hold data that is not from spesific type. Good way to hold such "un typed data" is using Generic. A "Generic Entity" that can hold any kind of data you need in the moment. For example, I create Generic entity called "Quadruple" that have 4 properties that will be from type you choose. If you create an instance of this entity like this:

Quadruplet<int,string,int,string> q1 = new Quadruplet<int,string,int,string>();

Quadruplet<bool,bool,Array,string> q2 = new Quadruplet<bool,bool,Array,string>();

q1 will be entity that can hold int, string, int & string and q2 will be entity that hold bool, bool, Array, string. No casting is needed.

List<Quadruplet<int, string, int, string>> quadrupletList = new List<Quadruplet<int, string, int, string>>();

quadrupletList  will be List of object from type Quadruplet<int,string,int,string>.  This kind of entitis can be very usuful in any kind of application, and it very reusable from application to another. 

In the file below, there are 4 entites: Duplet - hold 2 objects from any kind, Triplet 3 object (I know there is such class in 'System.Web.UI' but it holds 3 objects from the type 'Object' and casting will be needed),  Quadruplet for 4 objects and Quintet for 5. All those entities contains basic needed methods as Equals(object), operator ==, operator != and GetHashCode().

Those entities are NOT comming to replace the  "Customer", "Laboratory", "Shop" or any other specific needed entity. They are to help working with "un type" of data. Where the data is not from specific type or you don't want to make specific entitiy for that data.

SimpleGenericBusinessEntities.zip (4.26 kb)

Currently rated 4.3 by 6 people

  • Currently 4.333333/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by Miron on Saturday, February 16, 2008 6:57 AM
Permalink | Comments (1) | Post RSSRSS comment feed

Collect all controls from specific type

I got a simple "mission" to make a method that collect all the TextBox controls from any given control on the page (or from the Page itself).  As I like to do things in the most 'Generic' way, I finished with a simple method that collect all contols from any type you want.

This is the method that run recursive and collect all the controls from type T: 

        /// <summary>
        /// Loot recursive and collect the controls
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="contol"></param>
        /// <param name="list"></param>
        private static void LoopControls<T>(Control parentContol, List<T> list) where T : Control
        {
            foreach (Control ctrl in parentContol.Controls)
            {
                if (ctrl is T)
                {
                    list.Add(ctrl as T);
                }
                else
                {
                    if (ctrl.Controls.Count > 0)
                    {
                        LoopControls(ctrl, list);
                    }
                }
            }
        }

To start the 'collecting' process:

        /// <summary>
        /// Collect all the controls from type 'T'
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="contol"></param>
        /// <returns></returns>
        public static List<T> CollectControls<T>(Control parent) where T : Control
        {
            List<T> list = new List<T>();
            LoopControls(parent, list);
            return list;
        }

Drop this method in your 'Utilities' class, and its ready to go.  Now, To collect  all the TextBox in the page, just us it like this:

System.Collections.Generic.List<TextBox> l = Utils.CollectControls<TextBox>(Page);

and to collect all the Labels, just change the  '<TextBox>' to '<Label>'.

Using 'Generic' is very goot thing, and a lot of times, if you thing on the feutre and not focus only on the current mission when you write any method, you will end up using the Generic namespace.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:
Categories: ASP.NET | C# | Server side
Posted by Miron on Wednesday, February 06, 2008 8:50 PM
Permalink | Comments (3) | Post RSSRSS comment feed

Highlight search results in any page in the application

Recently I was working on part of an existing big project that one of it's main feature is searching (in this case it was medical info). There is search option in some different pages.  I was asked to add feature that 'highlight' the searching word/s in the search results. To do it with minimum changes for the existing code, I decided to do it using a 'Response Filter' that get the search word/s from the query and highligh it in the page. The 'highlight' is not more than to replace the 'searching word' with '<span style='background-color:yellow;color:black;'>searching word</span>'.

The idea was to get the html before it been send to the client, look for the 'searching words' and just replace them. The 'problem' is that we need to search the 'searching word' only in the text that is between the HTML tags and not within the tags. for that I used RegularExpression (ofcourse)and the not well know but powerfull class 'MatchEvaluator'.

How is it work:

First, we need to get the list of the searching words and concat them into one string seperates by '|' char.  The searching words are taken from the query string using the parameter 'highligh', and seperates by spaces (%20), or if it is exact phrase, it need to be between " (inverted commas).  For exmple, to highlight all the words 'searching' and 'words' in this article use this url: http://mironabramson.com/blog/post/2008/01/Highlight-search-results-in-any-page-in-the-application.aspx?highlight=searching%20words . To highligh the exact match 'searching words' use the url: http://mironabramson.com/blog/post/2008/01/Highlight-search-results-in-any-page-in-the-application.aspx?highlight=%22searching%20words%22 .   (To parse the searching words from the query string I used an old method I did long time ago 'GetSearchingWordsList' I'm sure it can be replace with RegularExpression version easly)

Second, we needs to find all the text that is not HTML tags. This will be done using RegularExpression:

 private static readonly Regex REGEX_TEXT_BETWEEN_TAGS = new Regex(@">\s*[^<]*<(?!/script)", RegexOptions.Compiled | RegexOptions.IgnoreCase);

 private static string HighlightText(string html, string hightlightWords)
 {
        MatchEvaluatorWithParameter matchEvulator = new MatchEvaluatorWithParameter(hightlightWords);
        return REGEX_TEXT_BETWEEN_TAGS.Replace(html, new MatchEvaluator(matchEvulator.Found));
 }

 The 'MatchEvaluator' in this case means that for every match of the regular expression, excute the method matchEvulator.Found

Third, we needs to find in every match our search words and replace it with '<span style='background-color:yellow;color:black;'>match</span>''

 private class MatchEvaluatorWithParameter
 {
      string _parameter;
      public MatchEvaluatorWithParameter(string parameter)

      {
           _parameter = parameter;
      }
      public string Found(Match m)
      {
           Regex replace = new Regex(_parameter, RegexOptions.IgnoreCase);
           return replace.Replace(m.Value, new MatchEvaluator(this.Replace));
       }
       private String Replace(Match m)
       {
           return "<span style='background-color:yellow;color:black;'>" + m.Value + "</span>";
       }
 }

To implement this ResponseFilter, you can use a new HttpModule or you can just assign the filter in an existing module in your application.  Note that like every other ResponseFilter you use, it must be exclude and not be performed if the request come from MS-AJAX control. 

To add it to an existing module, just add the 'HighlighterFilter' class, and in your module event, add:

  if (!IsAjaxPostBackRequest(app.Context) && app.Request.QueryString["highlight"] != null) {
         app.Response.Filter = new HighlighterFilter(app.Response.Filter, app.Server.UrlDecode(app.Request.QueryString["highlight"]));
  }

(If you are using compression module as I do, note that the highlight filter must come after you assign the compression filter, so it will be excute before.)  Downloading the code will help undersdand the concept more easly (as always, see the code always help to understand)

Maybe you will not find this Highlight filter usefull for your needs, but I guess some people saw a nice and useful example of using the powerfull of RegularExpression with the class 'MatchEvaluator'.

HighlighterFilter.cs (8.52 kb)

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by Miron on Saturday, January 12, 2008 5:55 AM
Permalink | Comments (1) | Post RSSRSS comment feed