當年讀大學的時候,曾經和人一起合租。合租的女生嬌生慣養,據說在家過了18年,連垃圾都沒倒過。
所以從和她合租的第一天起,我就扮演起了媽媽的角色。她不買菜,不做飯,不打掃房間,不刷碗,甚至不刷廁所。除了洗自己的內衣褲,她簡直過得像一個公主。
後來有一次我生病了,在床上躺了三天,她就讓屋子亂了三天,第四天我忍無可忍的爬起來把屋子打掃了一遍,扔掉了所有的垃圾,洗乾淨了所有她用過的杯子和
碗。兩個小時以後她回家了,帶了外賣回來,吃完之後,照例把用過的碗筷堆在了洗碗池裡。
我忍無可忍的生氣了,後果是之後的一個星期裡,她四處告訴所有的
人,我是一個多麼不近人情的人。你看,她那麼可憐,從小都沒有獨立生活過,長這麼大第一次離開爸爸媽媽,本來就方寸大亂。而我,從小就獨立生活,有嫻熟的
生活技巧,卻不肯對她有任何包容。於是有人來告訴我,你應該寬容一點,善良一點。我瞠目結舌,氣得回家哭。
我有個朋友,被男友劈腿了。幾年之後,男友和新歡結婚了,但是過得不幸福,是他們自己生病了,還是孩子生病了我已經忘記了,反正結果就是,他們回來找我的
朋友借錢,說是救命。我朋友二話不說的拒絕了,於是也有人告訴她,你應該善良一點,無論當年發生過什麼,這畢竟是一條命。朋友跟我吃飯的時候敲看桌子大
罵。我知道她為什麼要罵,當年她失戀以後萬念俱灰,喝酒喝到酒精中毒進醫院,她自己也是一條人命。
其實你會發現,這樣的場景在生活裡很多見。
好比你去買東西,一個比你歲數大的人插隊在你前面,如果你和他爭吵,那麼可能就會有人說你斤斤計較,不吃虧。好比你去坐瀏覽車,一個老人提出要和你交換上
下的位置,你如果拒絕了,可能就會有人說你小小年紀不懂得敬老,這麼點方便都不肯行。如果你的工作夥伴不負責
任,給你造成了巨大的困擾,而你生氣的時候他抹看眼淚從你的辦公室裡一路飛奔出去,那麼不要半天,你「嘴不饒人,把人活生生罵哭」的名聲可能就會傳遍全公
司。如果你過得還算不錯,而一個窮人侵犯了你的利益,那麼在你對他追究責任的時候,就可能會有人罵你為富不仁。
你看,總會有那麼多人,完全不問事情的起因緣由,就自顧自的站到看上去比較弱勢的那一方去。
後來有了網絡,我發現這種善良的人越來越多了。好比說,你總會看到殺人搶劫的新聞裡,有人在悲天憫人的說:如果有足夠的錢,誰會去搶劫呢。可是後來我發現
了一件很有趣的事,這些號稱別人被搶劫,被欺騙,被背叛,被壓榨,都仍舊應該心存寬仁的人,當自己利益被觸犯的時候,往往也是跳腳最快的那些人。
我親眼見過一個告訴我們「搶匪也是生計所迫才會去搶劫,值得同情」的人,在自己錢包丟了以後咒小偷全家去死。我也親眼見過一個指責我「你比我有錢多了,幹
嘛不肯幫我買單」的人,因為朋友找他借了個包,卻晚還了一天,就此和朋友翻了臉。從此我就明白了,原來那些整天都把善良掛在嘴邊的人,和善良兩個字實在沒
什麼關係。他們有些是希望世界上有越來越多的不懂得反抗和據理力爭的人,這樣,在他們想要不講道理佔便宜的時候,就會越發順遂。
另外一些,是想表達自己有多麼深邃的思想和多麼柔軟的心靈一一反正被傷害的也不是他們。當然還有一些,則是根本就沒有任何獨立思考的能力。他們選擇善良,只是因為做一個「善良」的人,要比做一個「講道理」的人輕鬆。你看,你只要站在看上去可憐的那一邊就好了。
就是這樣的幾種人湊在一起,而為了達到這樣的目的,他們無所謂事實的真相,無所謂事情的道理,無所謂那個真正在這件軎裡受了委屈或者做出了付出的人是多麼需要人的體諒和支持,他們只會為了那個自己想要達到的目的,沒有任何責任感的說出輕飄飄的空話。
一一你應該善良一點。真奇怪呢,我為什麼要善良一點?
所以在我想通了這個道理以後,我就選擇不要做一個「善良」的人了。 我只要做一個講道理,也負責任的人。我在意真相,我在意道理,我在意在一件事情裡真正付出努力並最後被辜負的那個人。我也在意一件事情裡無辜被傷害卻甚至不能為自己討個公道的那個人。
一件事情,我只想知道它本來的面目,我不想看誰流淚了,誰控訴了,誰顫巍巍的在風中發抖,或者誰喊叫得比較大聲。我不想聽誰說他是無心之失,聽誰說他是好心辦了壞事,聽誰說他只是不知道,不懂得,這些都不是他們該得到支持和原諒的理由。
無知即惡。蠢即惡。傷害即惡。這世上有些東西,起因比結果重要,比如追尋夢想。而有些事情,結果永遠重要過原因,比如傷害別人。如果我認為捅人一刀是表達友善的方式,於是去捅了人一刀,那麼這絕不說明對方應該因為我本無惡意而原諒我,相反這只能說明我是個白痴。
這世上最大的惡,往往都是以善良的名義四處橫行。
惡人的最大幫兇, 也常常是那些根本不需要為自己所標榜的「善良」做出任何實際付出的「善人」。
而這世上最可笑的事,莫過於善良本身,居然因為「善良」之名而寸步難行。
Saturday, April 20, 2013
Wednesday, April 17, 2013
Performance differences between debug and release builds
The C# compiler itself doesn't alter the emitted IL a great deal in the Release build. Notable is that it no longer emits the NOP opcodes that allow you to set a breakpoint on a curly brace. The big one is the optimizer that's built into the JIT compiler. I know it makes the following optimizations:
These are very important optimizations that can make a great deal of difference when, for example, you profile the Debug build of your app and compare it to the Release build. That only really matters though when the code is on your critical path, the 5 to 10% of the code you write that actually affects the perf of your program. The JIT optimizer isn't smart enough to know up front what is critical, it can only apply the "turn it to eleven" dial for all the code.
The effective result of these optimizations on your program's execution time is often affected by code that runs elsewhere. Reading a file, executing a dbase query, etc. Making the work the JIT optimizer does completely invisible. It doesn't mind though :)
The JIT optimizer is pretty reliable code, mostly because it has been put to the test millions of times. It is extremely rare to have problems in the Release build version of your program. It does happen however. Both the x64 and the x86 jitters have had problems with structs. The x86 jitter has trouble with floating point consistency, producing subtly different results when the intermediates of a floating point calculation are kept in a FPU register at 80-bit precision instead of getting truncated when flushed to memory.
Reference:
http://stackoverflow.com/questions/4043821/performance-differences-between-debug-and-release-builds
- Method inlining. A method call is replaced by the injecting the code of the method. This is a big one, it makes property accessors essentially free.
- CPU register allocation. Local variables and method arguments can stay stored in a CPU register without ever (or less frequently) being stored back to the stack frame. This is a big one, notable for making debugging optimized code so difficult. And giving the volatile keyword a meaning.
- Array index checking elimination. An important optimization when working with arrays (all .NET collection classes use an array internally). When the JIT compiler can verify that a loop never indexes an array out of bounds then it will eliminate the index check. Big one.
- Loop unrolling. Short loops (up to 4) with small bodies are eliminated by repeating the code in the loop body. Avoids the branch misprediction penalty.
- Dead code elimination. A statement like if (false) { /.../ } gets completely eliminated. This can occur due to constant folding and inlining. Other cases is where the JIT compiler can determine that the code has no possible side-effect. This optimization is what makes profiling code so tricky.
- Code hoisting. Code inside a loop that is not affected by the loop can be moved out of the loop.
- Common sub-expression elimination. x = y + 4; z = y + 4; becomes z = x;
- Constant folding. x = 1 + 2; becomes x = 3; This simple example is caught early by the compiler, but happens at JIT time when other optimizations make this possible.
- Copy propagation. x = a; y = x; becomes y = a; This helps the register allocator make better decisions. It is a big deal in the x86 jitter because it has so few registers to work with. Having it select the right ones is critical to perf.
These are very important optimizations that can make a great deal of difference when, for example, you profile the Debug build of your app and compare it to the Release build. That only really matters though when the code is on your critical path, the 5 to 10% of the code you write that actually affects the perf of your program. The JIT optimizer isn't smart enough to know up front what is critical, it can only apply the "turn it to eleven" dial for all the code.
The effective result of these optimizations on your program's execution time is often affected by code that runs elsewhere. Reading a file, executing a dbase query, etc. Making the work the JIT optimizer does completely invisible. It doesn't mind though :)
The JIT optimizer is pretty reliable code, mostly because it has been put to the test millions of times. It is extremely rare to have problems in the Release build version of your program. It does happen however. Both the x64 and the x86 jitters have had problems with structs. The x86 jitter has trouble with floating point consistency, producing subtly different results when the intermediates of a floating point calculation are kept in a FPU register at 80-bit precision instead of getting truncated when flushed to memory.
Reference:
http://stackoverflow.com/questions/4043821/performance-differences-between-debug-and-release-builds
To monitor detect slow performance of C# .NET framework application
You need to use profilers:
- Redgate ANTS Performance Profiler
- CLR Profiler for .NET Framework 4
- Visual Studio 2010 Performance Tools with Service Pack 1
- http://en.wikipedia.org/wiki/Code_profiler#Use_of_profilers
Update: You can also write messages in control points using Debug.Write. Then you need to load DebugView application that displays all your debug string with precise time stamp. It is freeware and very good for quick debugging and profiling.
Profilers are great for measuring.
But your question was "How can I determine where the slow parts of my code are?".
That is a different problem. It is diagnosis, not measurement.
I know this is not a popular view, but it's true.
It is like a business that is trying to cut costs.
One approach (top down) is to measure the overall finances, then break it down by categories and departments, and try to guess what could be eliminated. That is measurement.
Another approach (bottom up) is to walk in at random into an office, pick someone at random, and ask them what they are doing at that moment and (importantly) why, in detail.
Do this more than once.
That is what Harry Truman did at the outbreak of WW2, in the US defense industry, and immediately uncovered massive fraud and waste, by visiting several sites. That is diagnosis.
In code you can do this in a very simple way: "Pause" it and ask it why it is spending that particular cycle. Usually the call stack tells you why, in detail.
Do this more than once.
This is sampling. Some profilers sample the call stack. But then for some reason they insist on summarizing time spent in each function, inclusive and exclusive. That is like summarizing by department in business, inclusive and exclusive.
It loses the information you need, which is the fine-grain detail that tells if the cycles are necessary.
To answer your question:
Just pause your program several times, and capture the call stack each time. If your code is very slow, the wasteful function calls will be on nearly every stack. They will point with precision to the "slow parts of your code".
ADDED: RedGate ANTS is getting there. It can give you cost-by-line, and it is quite spiffy. So if you're in .NET, and can spare 3 figures, and don't mind waiting around to install & learn it, it can tell you much of what your Pause key can tell you, and be much more pretty about it.
Reference:
http://stackoverflow.com/questions/1077014/what-is-the-best-way-to-debug-performance-problems
http://stackoverflow.com/questions/485976/c-sharp-how-can-i-determine-where-the-slow-parts-of-my-code-are
- Redgate ANTS Performance Profiler
- CLR Profiler for .NET Framework 4
- Visual Studio 2010 Performance Tools with Service Pack 1
- http://en.wikipedia.org/wiki/Code_profiler#Use_of_profilers
Update: You can also write messages in control points using Debug.Write. Then you need to load DebugView application that displays all your debug string with precise time stamp. It is freeware and very good for quick debugging and profiling.
Profilers are great for measuring.
But your question was "How can I determine where the slow parts of my code are?".
That is a different problem. It is diagnosis, not measurement.
I know this is not a popular view, but it's true.
It is like a business that is trying to cut costs.
One approach (top down) is to measure the overall finances, then break it down by categories and departments, and try to guess what could be eliminated. That is measurement.
Another approach (bottom up) is to walk in at random into an office, pick someone at random, and ask them what they are doing at that moment and (importantly) why, in detail.
Do this more than once.
That is what Harry Truman did at the outbreak of WW2, in the US defense industry, and immediately uncovered massive fraud and waste, by visiting several sites. That is diagnosis.
In code you can do this in a very simple way: "Pause" it and ask it why it is spending that particular cycle. Usually the call stack tells you why, in detail.
Do this more than once.
This is sampling. Some profilers sample the call stack. But then for some reason they insist on summarizing time spent in each function, inclusive and exclusive. That is like summarizing by department in business, inclusive and exclusive.
It loses the information you need, which is the fine-grain detail that tells if the cycles are necessary.
To answer your question:
Just pause your program several times, and capture the call stack each time. If your code is very slow, the wasteful function calls will be on nearly every stack. They will point with precision to the "slow parts of your code".
ADDED: RedGate ANTS is getting there. It can give you cost-by-line, and it is quite spiffy. So if you're in .NET, and can spare 3 figures, and don't mind waiting around to install & learn it, it can tell you much of what your Pause key can tell you, and be much more pretty about it.
Reference:
http://stackoverflow.com/questions/1077014/what-is-the-best-way-to-debug-performance-problems
http://stackoverflow.com/questions/485976/c-sharp-how-can-i-determine-where-the-slow-parts-of-my-code-are
How to trace and debug in Visual C#
This article describes how to use the Debug and the Trace classes. These classes are available in the Microsoft .NET Framework. You can use these classes to provide information about the performance of an application either during application development, or after deployment to production. These classes are only one part of the instrumentation features that are available in the .NET Framework.
The steps in the Create a Sample with the Debug Class section demonstrate how to create a console application that uses theDebug class to provide information about the program execution.
When the program is run, you can use methods of the Debug class to produce messages that help you to monitor the program execution sequence, to detect malfunctions, or to provide performance measurement information. By default, the messages that the Debug class produces appear in the Output window of the Visual Studio Integrated Development Environment (IDE).
The sample code uses the WriteLine method to produce a message that is followed by a line terminator. When you use this method to produce a message, each message appears on a separate line in the Output window.
When you use the Assert method of the Debug class, the Output window displays a message only if a specified condition evaluates to false. The message also appears in a modal dialog box to the user. The dialog box includes the message, the project name, and the Debug.Assert statement number. The dialog box also includes the following three command buttons:
You can also direct output from the Debug class to destinations other than the Output window. The Debug class has a collection named Listeners that includes Listener objects.
Each Listener object monitors Debug output and directs the output to a specified target.
Each Listener in the Listener collection receives any output that the Debug class generates. Use the TextWriterTraceListenerclass to define Listener objects. You can specify the target for a TextWriterTraceListener class through its constructor.
Some possible output targets include the following:
Reference:
http://support.microsoft.com/kb/815788
Requirements
The following list outlines the recommended hardware, software, network infrastructure, and service packs that you need:- Microsoft Windows 2000 or Microsoft Windows XP or Microsoft Windows Server 2003
- Microsoft Visual C#
Description Of Technique
The steps in the Create a Sample with the Debug Class section demonstrate how to create a console application that uses theDebug class to provide information about the program execution.
When the program is run, you can use methods of the Debug class to produce messages that help you to monitor the program execution sequence, to detect malfunctions, or to provide performance measurement information. By default, the messages that the Debug class produces appear in the Output window of the Visual Studio Integrated Development Environment (IDE).
The sample code uses the WriteLine method to produce a message that is followed by a line terminator. When you use this method to produce a message, each message appears on a separate line in the Output window.
When you use the Assert method of the Debug class, the Output window displays a message only if a specified condition evaluates to false. The message also appears in a modal dialog box to the user. The dialog box includes the message, the project name, and the Debug.Assert statement number. The dialog box also includes the following three command buttons:
- Abort: The application stops running.
- Retry: The application enters debug mode.
- Ignore: The application proceeds.
You can also direct output from the Debug class to destinations other than the Output window. The Debug class has a collection named Listeners that includes Listener objects.
Each Listener object monitors Debug output and directs the output to a specified target.
Each Listener in the Listener collection receives any output that the Debug class generates. Use the TextWriterTraceListenerclass to define Listener objects. You can specify the target for a TextWriterTraceListener class through its constructor.
Some possible output targets include the following:
- The Console window by using the System.Console.Out property.
- A text (.txt) file by using the System.IO.File.CreateText("FileName.txt") statement.
Create a Sample with the Debug Class
- Start Visual Studio or Visual C# Express Edition.
- Create a new Visual C# Console Application project named conInfo. Class1 is created in Visual Studio .NET. Program.cs is created in Visual Studio 2005.
- Add the following namespace at top in Class1 or Program.cs.
using System.Diagnostics; - To initialize variables to contain information about a product, add the following declaration statements to Main method:
string sProdName = "Widget"; int iUnitQty = 100; double dUnitCost = 1.03; - Specify the message that the class produces as the first input parameter of the WriteLine method. Press the CTRL+ALT+O key combination to make sure that the Output window is visible.
Debug.WriteLine("Debug Information-Product Starting "); - For readability, use the Indent method to indent subsequent messages in the Output window:
Debug.Indent(); - To display the content of selected variables, use the WriteLine method as follows:
Debug.WriteLine("The product name is " + sProdName); Debug.WriteLine("The available units on hand are" + iUnitQty.ToString()); Debug.WriteLine("The per unit cost is " + dUnitCost.ToString()); - You can also use the WriteLine method to display the namespace and the class name for an existent object. For example, the following code displays the System.Xml.XmlDocument namespace in the Output window:
System.Xml.XmlDocument oxml = new System.Xml.XmlDocument(); Debug.WriteLine(oxml); - To organize the output, you can include a category as an optional, second input parameter of the WriteLine method. If you specify a category, the format of the Output window message is "category: message." For example, the first line of the following code displays "Field: The product name is Widget" in the Output window:
Debug.WriteLine("The product name is " + sProdName,"Field"); Debug.WriteLine("The units on hand are" + iUnitQty,"Field"); Debug.WriteLine("The per unit cost is" + dUnitCost.ToString(),"Field"); Debug.WriteLine("Total Cost is " + (iUnitQty * dUnitCost),"Calc"); - The Output window can display messages only if a designated condition evaluates to true by using the WriteLineIfmethod of the Debug class. The condition to be evaluated is the first input parameter of the WriteLineIf method. The second parameter of WriteLineIf is the message that appears only if the condition in the first parameter evaluates to true.
Debug.WriteLineIf(iUnitQty > 50, "This message WILL appear"); Debug.WriteLineIf(iUnitQty < 50, "This message will NOT appear"); - Use the Assert method of the Debug class so that the Output window displays the message only if a specified condition evaluates to false:
Debug.Assert(dUnitCost > 1, "Message will NOT appear"); Debug.Assert(dUnitCost < 1, "Message will appear since dUnitcost < 1 is false"); - Create the TextWriterTraceListener objects for the Console window (tr1) and for a text file named Output.txt (tr2), and then add each object to the Debug Listeners collection:
TextWriterTraceListener tr1 = new TextWriterTraceListener(System.Console.Out); Debug.Listeners.Add(tr1); TextWriterTraceListener tr2 = new TextWriterTraceListener(System.IO.File.CreateText("Output.txt")); Debug.Listeners.Add(tr2); - For readability, use the Unindent method to remove the indentation for subsequent messages that the Debug class generates. When you use the Indent and the Unindent methods together, the reader can distinguish the output as group.
Debug.Unindent(); Debug.WriteLine("Debug Information-Product Ending"); - To make sure that each Listener object receives all its output, call the Flush method for the Debug class buffers:
Debug.Flush();
Using the Trace Class
You can also use the Trace class to produce messages that monitor the execution of an application. The Trace and Debugclasses share most of the same methods to produce output, including the following:- WriteLine
- WriteLineIf
- Indent
- Unindent
- Assert
- Flush
Trace.WriteLine("Trace Information-Product Starting ");
Trace.Indent();
Trace.WriteLine("The product name is "+sProdName);
Trace.WriteLine("The product name is"+sProdName,"Field" );
Trace.WriteLineIf(iUnitQty > 50, "This message WILL appear");
Trace.Assert(dUnitCost > 1, "Message will NOT appear");
Trace.Unindent();
Trace.WriteLine("Trace Information-Product Ending");
Trace.Flush();
Console.ReadLine();
Verify That It Works
- Make sure that Debug is the current solution configuration.
- If the Solution Explorer window is not visible, press the CTRL+ALT+L key combination to display this window.
- Right-click conInfo, and then click Properties.
- In the left pane of the conInfo property page, under the Configuration folder, make sure that the arrow points toDebugging.
Note In Visual C# 2005 and in Visual C# 2005 Express Edition, click Debug in the conInfo page. - Above the Configuration folder, in the Configuration drop-down list box, click Active (Debug) or Debug, and then click OK. In Visual C# 2005 and in Visual C# 2005 Express Edition, click Active (Debug) or Debug in the Configurationdrop-down list box in the Debug page, and then click Save on the File menu.
- Press CTRL+ALT+O to display the Output window.
- Press the F5 key to run the code. When the Assertion Failed dialog box appears, click Ignore.
- In the Console window, press ENTER. The program should finish, and the Output window should display the output that resembles the following
Debug Information-Product Starting The product name is Widget The available units on hand are100 The per unit cost is 1.03 System.Xml.XmlDocument Field: The product name is Widget Field: The units on hand are100 Field: The per unit cost is1.03 Calc: Total Cost is 103 This message WILL appear ---- DEBUG ASSERTION FAILED ---- ---- Assert Short Message ---- Message will appear since dUnitcost < 1 is false ---- Assert Long Message ---- at Class1.Main(String[] args) <%Path%>\class1.cs(34) The product name is Widget The available units on hand are100 The per unit cost is 1.03 Debug Information-Product Ending Trace Information-Product Starting The product name is Widget Field: The product name isWidget This message WILL appear Trace Information-Product Ending - The Console window and the Output.txt file should display the following output:
The product name is Widget The available units on hand are 100 The per unit cost is 1.03 Debug Information-Product Ending Trace Information-Product Starting The product name is Widget Field: The product name is Widget This message WILL appear Trace Information-Product Ending
C:\Documents and Settings\User login\My Documents\Visual Studio 2005\Projects\conInfo\conInfo\bin\Debug
Complete Code Listing
using System;
using System.Diagnostics;
class Class1
{
[STAThread]
static void Main(string[] args)
{
string sProdName = "Widget";
int iUnitQty = 100;
double dUnitCost = 1.03;
Debug.WriteLine("Debug Information-Product Starting ");
Debug.Indent();
Debug.WriteLine("The product name is "+sProdName);
Debug.WriteLine("The available units on hand are"+iUnitQty.ToString());
Debug.WriteLine("The per unit cost is "+ dUnitCost.ToString());
System.Xml.XmlDocument oxml = new System.Xml.XmlDocument();
Debug.WriteLine(oxml);
Debug.WriteLine("The product name is "+sProdName,"Field");
Debug.WriteLine("The units on hand are"+iUnitQty,"Field");
Debug.WriteLine("The per unit cost is"+dUnitCost.ToString(),"Field");
Debug.WriteLine("Total Cost is "+(iUnitQty * dUnitCost),"Calc");
Debug.WriteLineIf(iUnitQty > 50, "This message WILL appear");
Debug.WriteLineIf(iUnitQty < 50, "This message will NOT appear");
Debug.Assert(dUnitCost > 1, "Message will NOT appear");
Debug.Assert(dUnitCost < 1, "Message will appear since dUnitcost < 1 is false");
TextWriterTraceListener tr1 = new TextWriterTraceListener(System.Console.Out);
Debug.Listeners.Add(tr1);
TextWriterTraceListener tr2 = new TextWriterTraceListener(System.IO.File.CreateText("Output.txt"));
Debug.Listeners.Add(tr2);
Debug.WriteLine("The product name is "+sProdName);
Debug.WriteLine("The available units on hand are"+iUnitQty);
Debug.WriteLine("The per unit cost is "+dUnitCost);
Debug.Unindent();
Debug.WriteLine("Debug Information-Product Ending");
Debug.Flush();
Trace.WriteLine("Trace Information-Product Starting ");
Trace.Indent();
Trace.WriteLine("The product name is "+sProdName);
Trace.WriteLine("The product name is"+sProdName,"Field" );
Trace.WriteLineIf(iUnitQty > 50, "This message WILL appear");
Trace.Assert(dUnitCost > 1, "Message will NOT appear");
Trace.Unindent();
Trace.WriteLine("Trace Information-Product Ending");
Trace.Flush();
Console.ReadLine();
}
}
Troubleshoot
- If the solution configuration type is Release, the Debug class output is ignored.
- After you create a TextWriterTraceListener class for a particular target, TextWriterTraceListener receives output from the Trace and the Debug classes. This occurs regardless of whether you use the Add method of the Trace or theDebug class to add TextWriterTraceListener to the Listeners class.
- If you add a Listeners object for the same target in the Trace and the Debug classes, each line of output is duplicated, regardless of whether Debug or Trace generates the output.
TextWriterTraceListener myWriter = new TextWriterTraceListener(System.Console.Out); Debug.Listeners.Add(myWriter); TextWriterTraceListener myCreator = new TextWriterTraceListener(System.Console.Out); Trace.Listeners.Add(myCreator);
Reference:
http://support.microsoft.com/kb/815788
what is the difference between lex and yacc
what is the difference between lex and yacc
vote up 1 vote down star
i have worked with lex for excuting some code whenever some regular expression is found, Can yacc do something more than that?if yes what
lex yacc
flag
asked Jul 27 at 18:04
Manik Mahajan
11●1
5 Answers
oldest newest votes
vote up 7 vote down
Yes, YACC is a parser, Lex is a lexical analyzer. They are typically used together: you Lex the string input, and YACC the tokenized input provided by Lex.
Now, a regular expression can only represent regular languages. One of the constraints of a regular language is the lack of "memory". You cannot define the rules for acceptance further down the string based on what has come before.
This is mostly clearly seen in the case of parenthesis. A regular language can't match nested parenthesis to the correct level. Or any other such structure. The grammars of (most) computer languages can and do, and, because of that, they can't be be parsed with a Lexer or a regular expression. That's where YACC comes in.
One can reverse the question as well. If YACC can do more, why not use it for the lexical analysis? Well, it so happens that you can verify the validity of a regular expression very efficiently, which is not the case of general grammars -- not to the same level. Still, YACC can do basic lexical analysis, if the lexical rules of the language are simple enough.
link|flag
edited Jul 29 at 20:58
laalto
answered Jul 27 at 18:11
Daniel
10.2k●1●15●40
+1 for explaining the difference between regular expressions and CFG's... – Polaris878 Jul 27 at 18:29
another, probably more important reason why yacc is not usually used for lexical analysis is because that is really pretty cumbersome. For instance a production rule to recognize a floating point number in Lex regular expressions is 1 line, about 15 characters. The equivalent Yacc rule would be about 10 lines, maybe 150 characters. – TokenMacGuy Jul 28 at 3:34
vote up 2 vote down
lex is for tokenizing input. That is, separating out your input into the lowest-level objects that your grammar defines. For example, you use lex to identify keywords, identifiers, strings, comments, whitespace, and so on.
yacc is for parsing your grammar. A grammar is a description of your language, typically defined in EBNF or some other context-free grammar. Once you describe your grammar to yacc, you can use it to run the actions of your tool when elements of the language are recognized. This might be, for example, constructing syntax trees for expression solving, defining scope objects, recording variable defintions, and so forth.
They are complimentary products.
link|flag
answered Jul 27 at 18:13
Christopher
3,299●11
+1 nice and succinct – skaffman Jul 29 at 21:02
vote up 1 vote down
lex and yacc are normally used together. This is how you usually construct an application using both:
Input Stream (characters) -> Lex (tokens) -> Yacc (Abstract Syntax Tree) -> Your Applcation
More generally, what Lex will do is read a source file, from the beginning, and try to match a number of regular expressions (lex has its own, special syntax for this, which is a bit different from perl or sed regular expressions), and will then invoke another program with each token it recognizes. Tokens may either just be a plain enumerated value, like for a key word or operator, or it might have some metadata attached, like for a literal value.
Lex is usually (though not neccesarily) used to invoke Yacc. Yacc uses a LALR parser algorithm, which roughly speaking, works by pushing each token onto a stack. If the stack has a sequence of tokens that it recognizes, it will pop all of the tokens, perform an action, and push another token back on the stack.
The proper vocabulary for what Yacc works on is actually terminals and non-terminals. A terminal is a token that it got from the invoking program (usually Lex), and a non-terminal is the result of matching a sequence on its stack.
Usually the actions taken by each Yacc rule are either to evaluate the result of a calculation that the rule corresponds with, or to produce an intermediate representation, like a syntax tree, for another application layer to process.
Yacc, like lex, can be used separate from the other. For instance, you could use Yacc by passing it individual characters from the source text, and use Yacc rules to recognize each kind of token. However Yacc is not designed to be very easy to use that way, and so the resulting lexer will be much more complex than an equivalent lexer in Lex. A more typical use would be to make a hand-coded lexer for reasons of either performance or because you need a smarter lexer. A common example of the second case is as used in C-like languages that have to know about previous uses of identifiers to know if they are used to describe types or variables.
link|flag
answered Jul 27 at 18:24
TokenMacGuy
8,530●4●19
vote up 1 vote down
lex is a lexical analyzer. It splits text up into tokens. Its power is roughly equivalent to regular expression matching. yacc is a parser generator. It takes a sequence of tokens (say, from lex) and interprets them as series of statements. Its power is roughly equivalent to context free grammars.
A typical application of lex and yacc is for implementing programming languages. lex tokenizes the input, breaking it up into keywords, constants, punctuation, etc. yacc then implements the actual computer language; recognizing a for statement, for instance, or a function definition.
In a practical sense, you often use lex to process input text into chunks. Then you use yacc to string those chunks together and process them into some larger meaning.
link|flag
edited Jul 27 at 23:22
answered Jul 27 at 18:12
Nelson
1,313●10
You mean "It takes a sequence of tokens (say, from lex) and..." don't you? – Chris Lutz Jul 27 at 19:16
thanks, corrected. – Nelson Jul 27 at 23:22
vote up 0 vote down
Lex is a tool for building lexical analyzers, that can do some rather stupid lexical stuff (like finding keywords). Yacc is a parser generator, that can create parsers for real computer languages. Its analysis is normally based upon the output of lex (which is a stream of tokens) and from this can create your parse-tree of the programming language -- something that is more than lex does.
Traditionally, compiler builders distinguish between lexical and syntactical analysis -- which are two important steps in a compiler (further ones to follow eg. code creation, optimization).
Reference:
http://blog.ijun.org/2013/04/parse-computer-langauge-syntax.html
vote up 1 vote down star
i have worked with lex for excuting some code whenever some regular expression is found, Can yacc do something more than that?if yes what
lex yacc
flag
asked Jul 27 at 18:04
Manik Mahajan
11●1
5 Answers
oldest newest votes
vote up 7 vote down
Yes, YACC is a parser, Lex is a lexical analyzer. They are typically used together: you Lex the string input, and YACC the tokenized input provided by Lex.
Now, a regular expression can only represent regular languages. One of the constraints of a regular language is the lack of "memory". You cannot define the rules for acceptance further down the string based on what has come before.
This is mostly clearly seen in the case of parenthesis. A regular language can't match nested parenthesis to the correct level. Or any other such structure. The grammars of (most) computer languages can and do, and, because of that, they can't be be parsed with a Lexer or a regular expression. That's where YACC comes in.
One can reverse the question as well. If YACC can do more, why not use it for the lexical analysis? Well, it so happens that you can verify the validity of a regular expression very efficiently, which is not the case of general grammars -- not to the same level. Still, YACC can do basic lexical analysis, if the lexical rules of the language are simple enough.
link|flag
edited Jul 29 at 20:58
laalto
answered Jul 27 at 18:11
Daniel
10.2k●1●15●40
+1 for explaining the difference between regular expressions and CFG's... – Polaris878 Jul 27 at 18:29
another, probably more important reason why yacc is not usually used for lexical analysis is because that is really pretty cumbersome. For instance a production rule to recognize a floating point number in Lex regular expressions is 1 line, about 15 characters. The equivalent Yacc rule would be about 10 lines, maybe 150 characters. – TokenMacGuy Jul 28 at 3:34
vote up 2 vote down
lex is for tokenizing input. That is, separating out your input into the lowest-level objects that your grammar defines. For example, you use lex to identify keywords, identifiers, strings, comments, whitespace, and so on.
yacc is for parsing your grammar. A grammar is a description of your language, typically defined in EBNF or some other context-free grammar. Once you describe your grammar to yacc, you can use it to run the actions of your tool when elements of the language are recognized. This might be, for example, constructing syntax trees for expression solving, defining scope objects, recording variable defintions, and so forth.
They are complimentary products.
link|flag
answered Jul 27 at 18:13
Christopher
3,299●11
+1 nice and succinct – skaffman Jul 29 at 21:02
vote up 1 vote down
lex and yacc are normally used together. This is how you usually construct an application using both:
Input Stream (characters) -> Lex (tokens) -> Yacc (Abstract Syntax Tree) -> Your Applcation
More generally, what Lex will do is read a source file, from the beginning, and try to match a number of regular expressions (lex has its own, special syntax for this, which is a bit different from perl or sed regular expressions), and will then invoke another program with each token it recognizes. Tokens may either just be a plain enumerated value, like for a key word or operator, or it might have some metadata attached, like for a literal value.
Lex is usually (though not neccesarily) used to invoke Yacc. Yacc uses a LALR parser algorithm, which roughly speaking, works by pushing each token onto a stack. If the stack has a sequence of tokens that it recognizes, it will pop all of the tokens, perform an action, and push another token back on the stack.
The proper vocabulary for what Yacc works on is actually terminals and non-terminals. A terminal is a token that it got from the invoking program (usually Lex), and a non-terminal is the result of matching a sequence on its stack.
Usually the actions taken by each Yacc rule are either to evaluate the result of a calculation that the rule corresponds with, or to produce an intermediate representation, like a syntax tree, for another application layer to process.
Yacc, like lex, can be used separate from the other. For instance, you could use Yacc by passing it individual characters from the source text, and use Yacc rules to recognize each kind of token. However Yacc is not designed to be very easy to use that way, and so the resulting lexer will be much more complex than an equivalent lexer in Lex. A more typical use would be to make a hand-coded lexer for reasons of either performance or because you need a smarter lexer. A common example of the second case is as used in C-like languages that have to know about previous uses of identifiers to know if they are used to describe types or variables.
link|flag
answered Jul 27 at 18:24
TokenMacGuy
8,530●4●19
vote up 1 vote down
lex is a lexical analyzer. It splits text up into tokens. Its power is roughly equivalent to regular expression matching. yacc is a parser generator. It takes a sequence of tokens (say, from lex) and interprets them as series of statements. Its power is roughly equivalent to context free grammars.
A typical application of lex and yacc is for implementing programming languages. lex tokenizes the input, breaking it up into keywords, constants, punctuation, etc. yacc then implements the actual computer language; recognizing a for statement, for instance, or a function definition.
In a practical sense, you often use lex to process input text into chunks. Then you use yacc to string those chunks together and process them into some larger meaning.
link|flag
edited Jul 27 at 23:22
answered Jul 27 at 18:12
Nelson
1,313●10
You mean "It takes a sequence of tokens (say, from lex) and..." don't you? – Chris Lutz Jul 27 at 19:16
thanks, corrected. – Nelson Jul 27 at 23:22
vote up 0 vote down
Lex is a tool for building lexical analyzers, that can do some rather stupid lexical stuff (like finding keywords). Yacc is a parser generator, that can create parsers for real computer languages. Its analysis is normally based upon the output of lex (which is a stream of tokens) and from this can create your parse-tree of the programming language -- something that is more than lex does.
Traditionally, compiler builders distinguish between lexical and syntactical analysis -- which are two important steps in a compiler (further ones to follow eg. code creation, optimization).
Reference:
http://blog.ijun.org/2013/04/parse-computer-langauge-syntax.html
parse computer langauge syntax
您好,我最近因專題需要,正在搞編譯器
EBNF 為一種用來描述程式語言的標準型式,可以讓規格保持簡潔。如XML規格即是用「EBNF」來撰寫的。
以上來自xml 台灣資訊網
其實pascal,java,ada,pyton,C 這些都有 bnf
另外還有一種叫做 EBNF,就我所知道C是沒有EBNF,因為C是蠻橫的語言^^
EBNF ,BNF 我也不太分的清楚...
google 可以找到很多她的規則
關於實作有Coco\r lex yacc bison 這些coco\r 採用LL(1),不支援C (花了我一個春假測它)
coco有一個好處,他用EBNF 做標準形式,架構可以通吃C#,java...etc
lex yacc 是gnu 拿來發展他們的編譯器,採用LALR,支援C 也有for java C#的版本
參考書籍有 lex & yacc 歐來裡的書, C程式語言 k & R 有BNF,林煙桂 系統程式
總而言之 BNF可以拿來搞編譯器 ,腳本編譯器,還可以開發一堆有規則描述的東西
以上有不對的請指教摟!!
唸資管的學生敬上^^
Reference:
http://blog.ijun.org/2009/11/what-is-difference-between-lex-and-yacc.html
EBNF 為一種用來描述程式語言的標準型式,可以讓規格保持簡潔。如XML規格即是用「EBNF」來撰寫的。
以上來自xml 台灣資訊網
其實pascal,java,ada,pyton,C 這些都有 bnf
另外還有一種叫做 EBNF,就我所知道C是沒有EBNF,因為C是蠻橫的語言^^
EBNF ,BNF 我也不太分的清楚...
google 可以找到很多她的規則
關於實作有Coco\r lex yacc bison 這些coco\r 採用LL(1),不支援C (花了我一個春假測它)
coco有一個好處,他用EBNF 做標準形式,架構可以通吃C#,java...etc
lex yacc 是gnu 拿來發展他們的編譯器,採用LALR,支援C 也有for java C#的版本
參考書籍有 lex & yacc 歐來裡的書, C程式語言 k & R 有BNF,林煙桂 系統程式
總而言之 BNF可以拿來搞編譯器 ,腳本編譯器,還可以開發一堆有規則描述的東西
以上有不對的請指教摟!!
唸資管的學生敬上^^
Reference:
http://blog.ijun.org/2009/11/what-is-difference-between-lex-and-yacc.html
Subscribe to:
Posts (Atom)