The main data structure issues that
you need to consider are as under:
Table
1
|
Issues
|
Implications
|
|
Choosing a collection without evaluating your needs
(size, adding, deleting, updating)
|
Reduced efficiency; overly complex code.
|
|
Using the wrong collection for a given task
|
Reduced efficiency; overly complex code.
|
|
Excessive type conversion
|
Passing value type to reference type causing boxing and
unboxing overhead, causing performance hit.
|
|
Inefficient lookups
|
Complete scan of all the content in the data structure,
resulting in slow performance.
|
|
Not measuring the cost of your data structures or
algorithms in your actual scenarios
|
Undetected bottlenecks due to inefficient code,
|
What are
Collections
There are two basic
types of collections: lists and dictionaries. Lists are index-based.
Dictionaries are key-based, which means you store a key with the value. Table 2
summarizes the various list and dictionary types provided by the .NET Framework
class libraries.
Collections are types that implement
the IEnumerable, ICollection, or IList interfaces. If the types implement
IDictionary separately or in
addition to these three interfaces, they are referred to as Dictionaries. Table 2 lists the guidelines
for each of these collection types.
Table
2
|
Type
|
Description
|
|
ArrayList
|
This is a dynamically sizable array. It is useful when
you do not know the required array size at design time.
|
|
Hashtable
|
This is a collection of key/value pairs that are
organized based on the hash code of the key. It is appropriate when you need to
search but not sort.
|
|
HybridDictionary
|
This uses a ListDictionary when the collection is
small, and switches to Hashtable
when the collection gets large.
|
|
ListDictionary
|
This is useful for storing 10 or less key/value pairs.
|
|
NameValueCollection
|
This is a sorted collection of associated String keys and String values that can be accessed either
with the key or with the index.
|
|
Queue
|
This is a first-in, first-out collection that implements
ICollection.
|
|
SortedList
|
This is a collection of key/value pairs that are sorted
by the keys and are accessible by key and by index.
|
|
Stack
|
This is a simple last-in, first-out collection of
objects.
|
|
StringCollection
|
This is a strongly typed array list for strings.
|
|
StringDictionary
|
This is a hash table with the key strongly typed to be a
string rather than an object.
|
The correct use of
data structures and algorithms plays a significant role in building
high-performance applications. Your choices in these areas can significantly
affect memory consumption and CPU loading.
The following guidelines help you to
use efficient data structures and algorithms:
● Choose an appropriate data structure.
● Pre-assign size for large dynamic growth data
types.
● Use value and reference types
appropriately.
Choose an
Appropriate Data Structure
Before choosing the
collection type for your scenarios, you should spend time analyzing your
specific requirements by using the following common criteria:
● Data storage. Consider how much data will
be stored. Will you store a few records or a few thousand records? Do you know
the amount of data to be stored ahead of time instead of at run time? How do you
need to store the data? Does it need to be stored in order or randomly?
● Type. What type of data do you need to
store? Is it strongly typed data? Do you store variant objects or value types?
● Growth. How will your data grow? What size
of growth? What frequency?
● Access. Do you need indexed access? Do you
need to access data by using a key-value pair? Do you need sorting in addition
to searching?
● Concurrency. Does access to the data need
to be synchronized? If the data is regularly updated, you need synchronized
access. You may not need synchronization if the data is read-only.
● Marshaling. Do you need to marshal your
data structure across boundaries? For example, do you need to store your data in
a cache or a session store? If so, you need to make sure that the data structure
supports serialization in an efficient way.
Pre-Assign Size
for Large Dynamic Growth Data Types
If you know that
you need to add a lot of data to a dynamic data type, assign an approximate size
up front wherever you can. This helps avoid unnecessary memory re-allocations.
Use Value and
Reference Types Appropriately
Value types are
stack-based and are passed by value, while reference types are heap-based and
are passed by reference. Use the following guidelines when choosing between
pass-by-value and pass-by-reference semantics:
●
Avoid passing large value types by value to
local methods. If the target method is in the same process or
application domain, the data is copied onto the stack. You can improve
performance by passing a reference to a large structure through a method
parameter, rather than passing the structure by value.
●
Consider passing reference types by value
across process boundaries. If you pass an object reference across a
process boundary, a callback to the client process is required each time the
objects’ fields or methods are accessed. By passing the object by value, you
avoid this overhead. If you pass a set of objects or a set of connected objects,
make sure all of them can be passed by value.
●
Consider passing a reference type when the
size of the object is very large or the state is relevant only within the
current process boundaries. For example, objects that maintain
handles to local server resources, such as files.
The following table highlights the main state management
issues:
|
State Management Issues
|
Implications
|
|
Stateful components
|
Holds server resources and can cause server affinity,
which reduces scalability options.
|
|
Use of an in-memory state store
|
Limits scalability due to server affinity.
|
|
Storing state in the database or server when the client
is a better choice
|
Increased server resource utilization; limited server
scalability.
|
|
Storing state on the server when a database is a better
choice
|
In-process and local state stored on the Web server
limits the ability of the Web application to run in a Web farm. Large amounts of
state maintained in memory also create memory pressure on the server.
|
|
Storing more state than you need
|
Increased server resource utilization, and increased time
for state storage and retrieval.
|
|
Prolonged sessions
|
Inappropriate timeout values result in sessions consuming
and holding server resources for longer than necessary.
|
Some of the best practices adopted for effective state
management are as under:
Minimize Session
Data
Keep the amount of session data
stored for a specific user to a minimum to reduce the storage and retrieval
performance overheads. The total size of session data for the targeted load of
concurrent users may result in increased memory pressure when the session state
is stored on the server, or increased network congestion if the data is held in
a remote store.
If you use session state, there are
two situations you should avoid:
●
Avoid storing any shared
resources. These are required by multiple requests and may result in
contention because the resource is not released until the session times out.
●
Avoid storing large collections and
objects in session stores. Consider caching them if they are required
by multiple clients.
Free Session
Resources As Soon As Possible
Sessions continue
to hold server resources until the data is explicitly cleaned up or until the
session times out.
You can follow a two-pronged
strategy to minimize this overhead. At design time, you should ensure that the
session state is released as soon as possible. For example, in a Web
application, you may temporarily store a dataset in a session variable so that
the data is available across pages. This data should be removed as soon as
possible to reduce load. One way to achieve this is to release all session
variables containing objects as soon as the user clicks on a menu item.
Avoid Accessing
Session Variables from Business Logic
Accessing session
variables from business logic makes sense only when the business logic is
interspersed along with presentation code as a result of tight coupling.
However, in the majority of cases,
you benefit from loosely coupled presentation and business logic, partitioned in
separate logical layers. This provides better maintainability and improved
scalability options. It is most frequently user interface-related state that
needs to be persisted across calls. Therefore, session-related state should be
part of the presentation layer. In this way, if the workflows of the user
interface change, it is only the presentation layer code that is affected.
Do You Know the
Number of Concurrent Sessions and Average Session Data per User?
Knowing the number
of concurrent sessions and the average session data per user enables you to
decide the session store. If the total amount of session data accounts for a
significant portion of the memory allocated for the ASP.NET worker process, you
should consider an out-of-process store.
Using an out-of-process state store
increases network round trips and serialization costs, so this needs to be
evaluated. Storing many custom objects in session state or storing a lot of
small values increases overhead. Consider combining the values in a type before
adding them to the session store.
HTTP compression
- is a simple way to improve site performance
and decrease bandwidth, with no configuration required on the client
side.
- is a capability built into both web servers and web browsers, to make better use of available bandwidth.
- HTTP protocol data is compressed before it is sent from the server.
How HTTP Compression Works
When
IIS receives a request, it checks whether the browser that sent the
request is compression-enabled. (Recent versions of Microsoft® Internet
Explorer and most other browsers typically send the following header if
they are compression-enabled: Accept-Encoding: gzip, deflate.) IIS then
determines whether the request is for a static file or for dynamic
content.
If the content of the file is static, IIS checks
whether the file has previously been requested and is already stored in
a compressed format in the temporary compression directory. If a
compressed version of the requested file is not found, IIS sends an
uncompressed version of the requested file to the client browser while
a background thread compresses the requested file. The newly compressed
file is then stored in the compression directory, and subsequent
requests for that file are serviced directly from the compression
directory. In other words, an uncompressed version of the file is
returned to the client unless a compressed version of the file already
exists in the compression directory.
If the file contains
dynamic content, IIS compresses the response as it is generated and
sends the compressed response to the browser. No copy of the file is
cached by the Web server.
The performance cost of compressing a
static file is modest and is typically incurred only once, because the
file is then stored in the temporary compression directory. The cost of
compressing dynamically generated files is somewhat higher because the
files are not cached and must be regenerated with each request. The
cost of expanding the file at the browser is minimal. Compressed files
download faster, which makes them particularly beneficial to the
performance of any browser that uses a network connection with
restricted bandwidth (a modem connection, for example).
If your
Web sites use large amounts of bandwidth or if you want to use
bandwidth more effectively, consider enabling HTTP compression, which
provides faster transmission times between IIS and compression-enabled
browsers regardless of whether your content is served from local
storage or a UNC resource. If your network bandwidth is restricted,
HTTP compression can be beneficial unless your processor usage is
already very high.
IIS provides the following compression options:
• Static files only.
• Dynamic application responses only.
• Both static files and dynamic application responses.
Dynamic
processing can affect CPU resources because IIS does not cache
compressed versions of dynamic output. If compression is enabled for
dynamic responses and IIS receives a request for a file that contains
dynamic content, the response that IIS sends is compressed every time
it is requested. Because dynamic compression consumes considerable CPU
time and memory resources, use it only on servers that have slow
network connections but CPU time to spare.
Compressed static responses can be cached and therefore do not affect CPU resources like dynamic responses do.
Compressing application response files is usually called dynamic compression.
Using HTTP Compression for Faster Downloads (IIS 6.0)
http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/25d2170b-09c0-45fd-8da4-898cf9a7d568.mspx?mfr=true
Enabling HTTP Compression (IIS 6.0)
http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/502ef631-3695-4616-b268-cbe7cf1351ce.mspx?mfr=true
Customizing the File Types IIS Compresses (IIS 6.0)
http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/5bce429d-c4a7-4f9e-a619-5972497b932a.mspx?mfr=true
http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/d52ff289-94d3-4085-bc4e-24eb4f312e0e.mspx?mfr=true
Speed Web delivery with HTTP compression
http://www.ibm.com/developerworks/web/library/wa-httpcomp/
Problem – While reading a CSV file using Microsoft Text Driver,
It interprets CSV file columns in it’s own way like if one the column
contains data specific to a date, then it only keep data which is in
proper format otherwise it put null against that.
Solution
– Create a schema.ini file which defines the structure of a CSV file in
turn gets interpreted automatically by driver itself in a desired
format.
Details -
Schema.ini files provide schema information about the records in a text file.
If
you create a DSN, the schema.ini file gets created automatically in the
folder where all your CSV files reside. But if you use connection
string, you have to create schema.ini file on your own.
When
the Text driver is used, the format of the text file is determined by
using a schema information file. The schema information file, which is
always named schema.ini and always kept in the same directory as the
text data source, provides the IISAM with information about the general
format of the file
Each Schema.ini entry specifies one of five characteristics of the table:
· The text file name
· The file format
· The field names, widths, and types
· The character set
· Special data type conversions
Example of a schema.ini file
Code:
[data.txt]
ColNameHeader=FALSE
Col1=Name Char Width 255
Col2=Company Char Width 255
Below are the links for detail information on this topic
http://msdn.microsoft.com/en-us/library/ms709353.aspx
http://www.codeproject.com/KB/database/FinalCSVReader.aspx
Code:
[data.txt]
ColNameHeader=FALSE
Col1=Name Char Width 255
Col2=Company Char Width 255
Below are the links for detail information on this topic
http://msdn.microsoft.com/en-us/library/ms709353.aspx
http://www.codeproject.com/KB/database/FinalCSVReader.aspx
MFC in Visual C++
6.0 has a problem with header notifications for the ListView control.
Although a handler can be added, in the current version it isn't
called. For instance, use Class Wizard or the WizardBar to add a
Windows Message Handler. If the ID for the ListView control is
highlighted, a number of notification messages are available for
selection. To sort the items when the header is clicked for a given
column, select the notification HDN_ITEMCLICK. An ON_NOTIFY message map
entry is generated, as well as a handler function. For the current
example, the entry appears as follows:
ON_NOTIFY(HDN_ITEMCLICK, IDC_LIST1, OnItemclickList1)
The
problem here is that the notification doesn't actually originate from
the ListView control; instead, the Header control created by the
ListView sends the notification. The message map entry listed above
does not work. The fix is simple, however, since the Header control
always has an ID of 0, the macro can be edited to work correctly:
ON_NOTIFY(HDN_ITEMCLICK, 0, OnItemclickList1)
Then, in the OnItemclickList1 handler, the SortItems call is made:
Code:
void CSortListDlg::OnItemclickList1(NMHDR* pNMHDR, LRESULT* pResult)
{
NMLISTVIEW *pLV = (NMLISTVIEW *) pNMHDR;
m_ctlListView.SortItems(SortFunc, pLV->iItem);
*pResult = 0;
}
The
notification message header (NMHDR) is actually a ListView
notification, NMLISTVIEW, that contains the index to the column that
was clicked. In this example, this is represented by iItem. More
complex lists might need to reference the iSubItem element of this
structure as well. The address of the callback function is passed to
SortItems, along with the column number which was clicked.
Read more: http://support.microsoft.com/kb/250614
While working on a web application, one of my team presented some weird behaviour on ASP.NET
FIrst observation: Session times out randomly while working on the application.
So we started observing the application closely to see what might be causing this. We came out with some more observations:
Detailed observation: Session times out when any of the user participates in certain scenario. Also, not only the specific session expires, but all the use sessions are expired. Further study shown that actually the app domain itself recycles.
We studied the activities in these specific scenario. We found that a certain implementation use to create folder, put some temporrary files inside it and once done, the folder and the files were deleted. The application recycles whenever the folder is deleted.
The technical reason: ASP.NET runs a File Monitor (FCN) that observes any change to the structure of the Virtual Directory. In case of any change the application is recycled.
Some forums said that tghe app_data folder within the application folder is immune to the condition. But upon testing, we found it otherwise.
Analysis: Lots of analysis:
Also we were observing session expiration initially. All session expires on application recycle unless the state is not in-process. So moving state in-proc to out-proc is a solution.
We found some other approaches as well.
Resolution: There are multiple solutions that can be taken up for this:
Compiled Solutions / workarounds so for
Sol 1: Use out of process session state.
Sol 2: Use Directory Junction between seperate Web folder and content folders. A directory Junction is a pointer to an external folder (outside the application folder/sub folder.
See http://blogs.msdn.com/toddca/archive/2005/12/01/499144.aspx for more details
Sol 3: Disable FCNotifications in ASP.NET2.0 by adding DWORD FCNMode =1 under HKLM\Software\Microsoft\ASP.NET key
Registry information
loadTOCNode(3, 'resolution'); To enable this hotfix, you must add the following DWORD value at the following registry key:
HKLM\Software\Microsoft\ASP.NET\FCNMode
The following table lists possible values for the FCNMode DWORD value and the behavior that is associated with each value.
Value Behavior
Does not exist This is the default behavior. For each subdirectory, the application will create an object that will monitor the subdirectory.
0 or greater than 2 This is the default behavior. For each subdirectory, the application will create an object that will monitor the subdirectory.
1 The application will disable File Change Notifications (FCNs). Smile
2 The application will create one object to monitor the main directory. The application will use this object to monitor each subdirectory.
More info at: http://support.microsoft.com/kb/911272/en-us
Sol 4: Do not delete any folder.
Most of the time solution 4 seems to be easy way out till MS releases fix for this problem. So we are following solution no 4 for the time being.
Further reading:
http://www.eggheadcafe.com/software/aspnet/32318159/modifying-application-fol.aspx
http://blogs.msdn.com/toddca/archive/2005/12/01/499144.aspx
http://forums.asp.net/p/966593/1209642.aspx
http://weblogs.asp.net/owscott/archive/2006/02/21/438678.aspx
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=240686
http://connect.microsoft.com/VisualStudio/feedback/Workaround.aspx?FeedbackID=240686
IE non-standard onPropertyChange is a huge problem in most of the places. I was working on a work of moving an application designed to work on IE to a cross-browser standard. For some of the forms, there is a pop up and on the close button of the pop up, it used to update some of the fields in the opener page as:
function fnClose(rowid){
var taxHTML = document.getElementById("taxvalues").innerHTML;
window.opener.document.getElementById("taxvalues").innerHTML=taxHTML;
window.opener.document.getElementById("hdnTax").value=rowid;
//There is a event handler on this element in the opener using "onPropertyChange=fnPopClosed(this.value);"
window.close();
}
There is a hidden field in the opener and onPropertyChange event of the hidden field was handled to accomplish the final task. On the opener page there was a call to a javascript function triggered by the onPropertyChange event of the hidden field. Though IE gracefully handles the situation, Firefox and other browsers have never heard of such an event. So there is no activity.
I studied a lot of techniques to emulate the onPropertyChange event including adding a eventlistener. After around three hours of tweaking different ideas, I finally wired up the same in a different technique. I called the javascript method in the opener page directly from the pop up like this:
function fnClose(rowid){
var taxHTML = document.getElementById("taxvalues").innerHTML;
window.opener.document.getElementById("taxvalues").innerHTML=taxHTML;
window.opener.fnPopClosed(rowid);
window.close();
}
And I got what I wished to have.
Enjoy javascripting....
So now also a new look of the site. Its completely away from the standard themes available. Want to know the details? I merged one of the themes available for BlogEngine with the layout of another good looking website.
I am not a web designer. So there will be plenty of mistakes, at least I expect it to be so. Pleare report all the problems to me at theGeek@geekays.net and I will update the same as soon as possible. Thats my promise.
Want to have it as a standard theme? Probably I shall take some time to make it a standard theme. Actually there are a lot of CSS inside it, some of them are not required as of now. I need to clear up the clutter and refactor the same.
Waiting for your feedback.
So, last midnight, I have shifted this site from dasBlog to BlogEngine. I started with dasBlog in the starting of this year. But after going through the features and enhancements in BlogEngine, I shifted out for the better. The specific reasons are a newer codebase, better theme support and other better features. One of the major feature that caused me to shift is the static front page capability. I wanted to have a site where I can add blogs. dasBlog let me add page to the blog and the web site converts to a blog site immediately. I am not saying any negative for dasBlog. I am just comparing my requirements. So I felt BlogEngine met my requirements.
Okay, let me share the details of the activities:
1. I downloaded BlogEngine last week and set it up. Seting up was just as smooth as butter. There is no configuration changes in .config files. Just unzipping the downloaded contents and pointing the folder in the IIS.
2. Exported the earlier dasBlog entries to BlogML. This is not supported in dasBlog. There is a very good tool Merill Fernando. Look his blog: http://www.merill.net/post/2008/03/DasBlog-to-BlogML-Converter.aspx. The converter tool is available at: http://code.msdn.microsoft.com/DasBlogML.
3. Import BlogML to BlogEngine. Use the Settings tab in the control panel and using the bottom option just import the blogML and PRESTO! you have done it!!
4. Uploading: Removed the content from my existing site, except the folders which contain images and other files which I am using, like images etc. Then simply uploaded the local content to the web server.
So its up and running. Finished putting my entry for the new site at midnight!!
So now I have moved to BlogEngine from DasBlog.
The details are just coming.