Archive for the ‘C#’ Category

Some ASP.NET Benchmark data

Sunday, January 13th, 2008

This is just a very simple and rough benchmark test, I use my own desktop computer running Windows XP professional and many process (including the heavy weight Visual Studio 2008) and ASP.NET’s development server which comes with Visual Studio. I believe after deploy it on IIS under Windows Server box will archive much better performance.

I use Apache bench to test, the parameter I used is “-n 1000 -c 100″, means send 1000 requests and concurrent number is 100.

Quick view of results:

  Test Request per second [#/sec] (mean)
1 Simple aspx view (same as below MVC’s view aspx file) 285.71
2 Simple asp.net MVC 232.73
3 ASP.net MVC with another MVC request from inside 174.39
4 ASP.net MVC with a simple user control rendered by RenderUserControl() 218.43
5 ASP.net MVC with a simple user control rendered by user control tag 235.29

Of course a simple .aspx page archive the best performance, MVC add very minimal overhead to it.

Use tag to render user control have almost no overhead ( I believe it has been complied inside, like source level include),  RenderUserControl() have a small overhead.

shinakuma’s RenderComponent() have some overhead in performance since he use “ProcessRequest()” which actually initialize a whole server side MVC cycle.  (Java’s jsp:include have same heavy weight behavior as I tested before.) If we can find out a better solution to archive a much lighter weight performance it would be great.

Details outputs:

Test #1: Simple aspx view (same as below MVC’s view aspx file)

D:\Program Files\Apache Software Foundation\Apache2.2\bin>ab -n 1000 -c 100 http://localhost:64701/views/Home/Index.aspx
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd,
http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests

Server Software:        ASP.NET
Server Hostname:        localhost
Server Port:            -835

Document Path:          /views/Home/Index.aspx
Document Length:        1176 bytes

Concurrency Level:      100
Time taken for tests:   3.500000 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      1410000 bytes
HTML transferred:       1176000 bytes
Requests per second:    285.71 [#/sec] (mean)
Time per request:       350.000 [ms] (mean)
Time per request:       3.500 [ms] (mean, across all concurrent requests)
Transfer rate:          393.14 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   2.3      0      15
Processing:    78  331  71.5    343     515
Waiting:       78  328  71.2    328     484
Total:         78  331  71.4    343     515

Percentage of the requests served within a certain time (ms)
  50%    343
  66%    343
  75%    343
  80%    343
  90%    406
  95%    468
  98%    484
  99%    484
100%    515 (longest request)

Test #2:  Simple ASP.NET MVC (empty controller, simple asp.net view page with default master page)

D:\Program Files\Apache Software Foundation\Apache2.2\bin>ab -n 1000 -c 100 http
://localhost:64701/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd,
http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests

Server Software:        ASP.NET
Server Hostname:        localhost
Server Port:            -835

Document Path:          /
Document Length:        1168 bytes

Concurrency Level:      100
Time taken for tests:   4.296875 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      1402000 bytes
HTML transferred:       1168000 bytes
Requests per second:    232.73 [#/sec] (mean)
Time per request:       429.688 [ms] (mean)
Time per request:       4.297 [ms] (mean, across all concurrent requests)
Transfer rate:          318.60 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   2.6      0      46
Processing:    62  408  71.4    421     531
Waiting:       62  403  71.1    421     515
Total:         62  408  71.5    421     546

Percentage of the requests served within a certain time (ms)
  50%    421
  66%    437
  75%    437
  80%    437
  90%    453
  95%    468
  98%    484
  99%    500
100%    546 (longest request)

 

Test#3: ASP.NET MVC with another MVC request from inside of the view (refer to RenderComponent in this posts)

D:\Program Files\Apache Software Foundation\Apache2.2\bin>ab -n 1000 -c 100 http
://localhost:64701/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd,
http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests

Server Software:        ASP.NET
Server Hostname:        localhost
Server Port:            -835

Document Path:          /
Document Length:        2133 bytes

Concurrency Level:      100
Time taken for tests:   5.734375 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      2367000 bytes
HTML transferred:       2133000 bytes
Requests per second:    174.39 [#/sec] (mean)
Time per request:       573.438 [ms] (mean)
Time per request:       5.734 [ms] (mean, across all concurrent requests)
Transfer rate:          403.01 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   2.9      0      31
Processing:    62  543  96.6    562     640
Waiting:       46  539  96.6    562     640
Total:         62  543  96.7    562     640

Percentage of the requests served within a certain time (ms)
  50%    562
  66%    578
  75%    578
  80%    578
  90%    593
  95%    593
  98%    625
  99%    625
100%    640 (longest request)

Test #4: ASP.NET MVC with a simple user control rendered by html.RenderUserControl() from MVCToolKit

D:\Program Files\Apache Software Foundation\Apache2.2\bin>ab -n 1000 -c 100 http
://localhost:64701/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd,
http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests

Server Software:        ASP.NET
Server Hostname:        localhost
Server Port:            -835

Document Path:          /
Document Length:        1212 bytes

Concurrency Level:      100
Time taken for tests:   4.578125 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      1446000 bytes
HTML transferred:       1212000 bytes
Requests per second:    218.43 [#/sec] (mean)
Time per request:       457.813 [ms] (mean)
Time per request:       4.578 [ms] (mean, across all concurrent requests)
Transfer rate:          308.42 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   3.2      0      31
Processing:   140  426  85.3    453     531
Waiting:      109  423  87.7    453     515
Total:        140  427  85.1    453     531

Percentage of the requests served within a certain time (ms)
  50%    453
  66%    468
  75%    468
  80%    468
  90%    484
  95%    484
  98%    500
  99%    500
100%    531 (longest request)

 

Test #5: ASP.NET MVC with same user control rendered by tag

D:\Program Files\Apache Software Foundation\Apache2.2\bin>ab -n 1000 -c 100 http
://localhost:64701/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd,
http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests

Server Software:        ASP.NET
Server Hostname:        localhost
Server Port:            -835

Document Path:          /
Document Length:        1212 bytes

Concurrency Level:      100
Time taken for tests:   4.250000 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      1446000 bytes
HTML transferred:       1212000 bytes
Requests per second:    235.29 [#/sec] (mean)
Time per request:       425.000 [ms] (mean)
Time per request:       4.250 [ms] (mean, across all concurrent requests)
Transfer rate:          332.24 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   3.2      0      31
Processing:    78  401  69.5    421     468
Waiting:       78  398  69.5    421     453
Total:         78  401  69.5    421     468

Percentage of the requests served within a certain time (ms)
  50%    421
  66%    421
  75%    437
  80%    437
  90%    437
  95%    437
  98%    453
  99%    453
100%    468 (longest request)

Co-exist of ASP.NET MVC and Web forms

Sunday, January 13th, 2008

MVC makes a web application’s architect quite clear, however in my point of view, MVC is not a great for all solution.

One of MVC’s pain points is handling the form submission. For a simple form submission, generally you need 2 action: ActionShowForm and ActionUpdateForm, the first action show a web form interface to let user edit the form, the second action is for submission. If you use server side form validation, it will be a little bit more complicated (depends on how you display those validation information to users).

Traditional ASP.Net web form can handle above form submission in very simple and straight forward way, with just one .aspx file and one code behind .cs file, complex web form handling is a easy and enjoyable work. It’s also very easy and without too much code to use ASP.NET ajax’s update panel to get fancy update free ajax form effect.

MVC frameworks has been used in Java web developing for a long time, look at what’s Java’s new movement?   It’s JSF(Java Server Face), something really like ASP.NET, it also have something similar to “view state” and “post back”. What a interesting thing it is:  after so many years working with MVC, Java guys are looking to web form alike “new” technology,  and after using web forms for so many years, ASP guys are so exciting about MVC. :)

In one of my experiment project, I used ASP.NET MVC together with the web form.  MVC is used as the major part of the web site, Web forms are used for all those form handling, they co-exist pretty well.

I create a folder named “forms”, and put all web forms files (aspx and cs) inside this folder. Though it’s ok to put them inside the “view” folder, I separated them because they are different  in modeling. The web forms share the same “Model” part (if it require to access the “model”), I use session data object to pass data in/out the  web forms.

Implement Java servlet filter alike function in ASP.NET MVC

Saturday, December 15th, 2007

As a Java guys who turn to .NET, I always look for some nice stuff in Java inside .Net’s. 

Java’s Servlet filter is something good, I think in ASP.NET the similar concept is httpmodule (correct me if I am wrong). Filter is a great place to implement authentication, logging, auditing, data compression, transcoding, data transforming (e.g. XSLT), …etc.

When I am planning to add OpenID into ASP.NET MVC application, I couldn’t find a good enough place to put the OpenID authentication codes.

ASP.NET’s form authentication mode should be able to work together with ASP.NET MVC, I already see a blog article talk about this. The only change is configure an action URL in the form action loginUrl . Monorails also suggested its user to use this way.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    ...
    <system.web>
        <authentication mode="Forms">
            <forms name="auth" loginUrl="auth/login">
            ...
            </forms>
        </authentication>

I wish ASP.NET MVC could also support something like MonoRails’ filter. MonoRails filters are executed before and|or after actions. It is useful for security, dynamic content and to keep away repetitive code.

Fortunately, on Controller class there are some virtual functions which enable we do something before, after the action:

protected virtual bool OnError(string actionName, MethodInfo methodInfo, Exception exception);
protected virtual void OnPostAction(string actionName, MethodInfo methodInfo);
protected virtual bool OnPreAction(string actionName, MethodInfo methodInfo);

We can the implement some of our own controller class, so we can make it easier to implement something like Java servlet filters (and its chain).

Still learning… so maybe I am not that right…

ASP.NET Open ID Consumer Lib/Controls

Friday, December 14th, 2007

Just found this one:

ExtremeSwank OpenID Consumer (Supports OpenID 1.1, 2.0, and extensions)

I dislike the previous one which based on JanRain, like it said:

Unfortunately, many of the complaints are that it’s written in Boo (a language based heavily on Python). While .NET is all about using whatever language you want to, Boo unfortunately requires a separate DLL for deployment, and it’s not very mainstream in the .NET world yet so that makes it somewhat difficult to justify supporting and maintaining in an existing, or new, project.

ExtremeSwank OpenID lib is a client OpenID library and User Control set written completely in C#.

There are two versions of this library:

  • OpenID Consumer
    Provides a fully featured OpenID 1.1 and 2.0 Consumer that supports Stateful and Stateless modes. Immediate mode is supported, but communication of data through the User Agent must be handled by the web application or a UserControl.
  • OpenID Simple Consumer
    Provides a simplified OpenID 1.1 and 2.0 Consumer that only supports Stateless (Dumb) authentication. It has the added benefit of running on systems that require partial-trust.

Just wrote a quick sample to use ExremeSwank OpenID consumer with ASP.NET MVC, yeah, it works great ! 

image

At this time I just write some quick and dirty code, I new an OpenIDConsumer() directly from an Action method, call BeginAuth() if the requestMode is RequestedMode.None, and call renderview() if auth succ.

The better solution should implement a servlet filter alike (in ASP.NET, should be httpmodule) authentication filter to do so, I will implement it later.

Update:

Just read this blog: ASP.Net MVC Membership Basics, make a “RequireAuthController” as base controller class for all those action which need auth is a better idea than implement an authentication filter, maybe I will modify from his sample and add openid in.

ASP.NET MVC + Dynamic Data Sample

Friday, December 14th, 2007

ASP.NET MVC and Dynamic Data are both nice stuff, can they work together? sure! David just blog about it:

Will this work with MVC?

In this initial Preview, Dynamic Data is mostly targeting ’standard’ ASP.NET pages, but we are absolutely planning to support Dynamic Data for MVC.  And the good news is that you can actually try this today!  To do this:

This was completely unadvertised, so most folks probably didn’t see it, but it’s in there for you to play with!  Start by just running it, and then look through the source code, which is all part of the solution.  Of course, it’s all very preliminary, and far from feature complete, but it should give you an idea of where we’re heading.  If there is enough interest, I’ll try to make a screen cast that shows it.

The ASP.NET MVC Toolkit provides HTML rendering helpers and dynamic data support for MVC, it’s separated from the CTP install package.

This is how the blog sample works:

Controller, inherit from DynamicDataController, defined inside the toolkit.

namespace Blog.Controllers {
    public class CommentController : DynamicDataController<Comment> { }
}

The DynamicDataController will render some aspx views default inside “view/shared”.  In the example, the view post define its own view in “view/post/Show.aspx”, since ASP.NET MVC’s RenderView(”Show”) will fist look inside view/<controllerName>/<viewname> first, the customized version will be used over the shared one.

The default “Dynamic Data web” project created by template have very different structure than the MVC Dynamic Data demo project.  I wish in the next release, tge MVCDynamicData can be included by default.

What I expecting is the feature that user can drag database table columns into a web form, and generate the CRUD scaffold with those web form, in that case, database centric web develop will be much easier.  (though FoxPro, PowerBuild, Delphi, or maybe VB,  have this kind of feature for many years)  That’s something that I expected for a long time, can’t believe  this kind of solution doesn’t exist before.

class vs struct, reference vs value

Sunday, November 18th, 2007

Another different between C# Java is, C# support “struct” data type, which is like a downgraded “class” (doesn’t support iherite and finalizer), and important: struct is value not reference.

Like Java the primitive types “int”, “float”, “bool”, “char” are also value, not reference.

A much much more detailed articles: http://www.albahari.com/value%20vs%20reference%20types.html

A little bit consusing, I am still not yet understanding why C# keep “struct”, for compatible with C? If someone know the advantage of using “struct” in C# pls. let me know, thanks.

SubSonic: cool stuff

Saturday, November 17th, 2007

image

C#, ASP.NET based open source project, which bring the best part of RoR (ruby on rails) to ASP.net.

Super cool.

David Hayden’s LINQ to SQL Turtorials

Saturday, November 17th, 2007

LINQ To SQL Tutorials:

LINQPad: great tool to learn LINQ for SQL

Saturday, November 17th, 2007

via: http://www.linqpad.net/

LINQPad lets you interactively query SQL databases in a modern query language: LINQ.  Kiss goodbye to SQL Management Studio!

LINQPad supports everything in C# 3.0 and Framework 3.5:

  • LINQ to SQL
  • LINQ to Objects
  • LINQ to XML

LINQPad is also a terrific tool for learning LINQ: it comes preloaded with 200 examples from the recently released C# 3.0 in a Nutshell.  There’s no better way to experience the coolness of LINQ and functional programming.

LINQPad is free and needs no installation: just download and run.  The executable is only 1MB and is self-updating.

LINQ to SQL performance issue

Saturday, November 17th, 2007

LINQ is one of the greatest feature in C#3.0, LINQ to SQL is an O/RM (object relational mapping) implementation that included, we can do CRUD on the database using LINQ. LINQ to SQL also supports transactions, views, and stored procedures.

Now seemed the only issue for me is if LINQ for SQL performance is good enough.

There are already some talks on LINQ to SQL performance:

Database Performance, Correctness, Compostion, Compromise, and Linq too (http://blogs.msdn.com/ricom/archive/2007/08/31/database-performance-correctness-compostion-compromise-and-linq-too.aspx)

LINQ to SQL Compiled Queries(http://devauthority.com/blogs/jwooley/archive/2007/09/05/75645.aspx)

Compiled Queries in LINQ to SQL - performance considerations and entity caching (http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1438097&SiteID=1)

Improving Performance With LINQ(http://www.singingeels.com/Articles/Improving_Performance_With_LINQ.aspx)

LINQ To SQL and Visual Studio 2008 Performance Update(http://www.davidhayden.com/blog/dave/archive/2007/09/28/LINQToSQLVisualStudio2008PerformanceUpdate.aspx)