我知道.NET和Mono是二进制兼容的,但是给定一组源代码,csc和mcs会产生完全相同的100%相同的二进制CLI可执行文件吗?是否能够判断可执行文件是使用csc还是mcs编译的?
编译器是否在运行时编译MSIL或Native代码中的"无法访问代码"?
有什么静态编译器可以在JIT无法优化时的示例吗?
例如,.NET JIT无法完成C++编译器的一些优化?
假设我有:
int counter;
++counter;
Run Code Online (Sandbox Code Playgroud)
问题是:内存(堆栈)中发生了什么?如果在堆栈中创建了一个新变量并复制了上一个变量的值并添加了+1或者使用了temp变量,那么在那里添加+1然后在计数器中添加新值?
我正在尝试使用WinDbg和SOS调试用于教育目的的.NET托管代码应用程序.
Module Module1
Sub Main()
Console.Read()
throwExceptionMethod()
End Sub
Private Sub throwExceptionMethod()
Dim localString As String = "bad string"
If localString = "bad string" Then
Throw New System.NotSupportedException("Can't process the string.")
End If
End Sub
End Module
Run Code Online (Sandbox Code Playgroud)
在调试模式下编译时,我可以看到抛出异常的方法和破坏我的应用程序的本地字符串.
输出!CLRStack命令:
0:000> !CLRStack
OS Thread Id: 0x1148 (0)
DBGHELP: mscorwks - public symbols
C:\Program Files\Debugging Tools for Windows (x64)\sym\mscorwks.pdb\EC7B2AF3D7A74E1FB2A04CB8AF5F867A1\mscorwks.pdb
DBGHELP: ntdll - public symbols
C:\Program Files\Debugging Tools for Windows (x64)\sym\ntdll.pdb\9D04EB0AA387494FBD81ED062072B99C2\ntdll.pdb
DBGHELP: mscoreei - public symbols
C:\Program Files\Debugging Tools …Run Code Online (Sandbox Code Playgroud) 我根据MSDN正确设置了Windbg .问题是当我在调试模式下获得转储文件时,我可以正确地看到调用堆栈(符号被正确加载).
000000f758b6eac0 00007ffb5be60559 System.Number.StringToNumber(System.String, System.Globalization.NumberStyles, NumberBuffer ByRef, System.Globalization.NumberFormatInfo, Boolean)
000000f758b6eb20 00007ffb5b0cd791 System.Number.ParseInt32(System.String, System.Globalization.NumberStyles, System.Globalization.NumberFormatInfo)
000000f758b6ec70 00007ffafcc60214 ConsoleApplication1.Program.ConvertToInt(System.String)
000000f758b6ecb0 00007ffafcc60105 ConsoleApplication1.Program.Main()
000000f758b6f030 00007ffb5c3b4113 [GCFrame: 000000f758b6f030]
Run Code Online (Sandbox Code Playgroud)
当我在发布模式下获取转储文件时,缺少某些信息,特别是在调试模式下可见的方法名称"ConvertToInt".
00000081df98c710 00007ffafcc701e1 ConsoleApplication1.Program.Main() [C:\Written Programs\ConsoleApplication1\ConsoleApplication1\Program.cs @ 29]
00000081df98e6a8 00007ffb5c3eb915 [HelperMethodFrame: 00000081df98e6a8]
00000081df98e790 00007ffb5be60559 System.Number.StringToNumber(System.String, System.Globalization.NumberStyles, NumberBuffer ByRef, System.Globalization.NumberFormatInfo, Boolean)
00000081df98e7f0 00007ffb5b0cd791 System.Number.ParseInt32(System.String, System.Globalization.NumberStyles, System.Globalization.NumberFormatInfo)
00000081df98e940 00007ffafcc700e0 ConsoleApplication1.Program.Main() [C:\Written Programs\ConsoleApplication1\ConsoleApplication1\Program.cs @ 23]
Run Code Online (Sandbox Code Playgroud)
我在这里做错了吗?
再加上HelperMethodFrame是什么意思?除了在调试模式下,即使没有程序.pdb文件,我仍然可以正确看到调用堆栈.究竟是什么.pdb文件用于.我已经阅读了定义和所有内容,只需要一个关于它如何与Windbg一起使用的实用答案?
第二次尝试表达这一点:
我正在采取一些步骤来掌握一些MSIL.
我一直听到"评估堆栈"被称为堆栈,操作在加载,使用等时被推送和加载.
因此,给出以下代码:
public class Program
{
public static void Main()
{
var message = GetMessage();
Console.WriteLine(message);
}
public static string GetMessage()
{
return "Hello World!";
}
}
Run Code Online (Sandbox Code Playgroud)
MSIL看起来如此:
.class public auto ansi beforefieldinit Program
extends [mscorlib]System.Object
{
.method public hidebysig specialname rtspecialname instance void .ctor () cil managed
{
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
}
.method public hidebysig static string GetMessage () cil managed
{
.locals init (
[0] string V_0
)
IL_0000: nop …Run Code Online (Sandbox Code Playgroud) 对于我的一个项目,我使用了很多分支。思考:
if (foo) { do something }
else if (bar) { do something }
else if (bar2) { do something }
... and so on
Run Code Online (Sandbox Code Playgroud)
和
if (foo) { do something }
if (bar) { do something }
if (bar2) { do something }
... and so on
Run Code Online (Sandbox Code Playgroud)
我一直想知道的是,做子表达式和/或逻辑消除来加速它是否有意义。为了完整起见,您可以假设所有这些都在一个函数中。比如说,如果foo和bar有一个共同的子表达式,你可以这样写:
if (commonSubExpr)
{
if (foo without commonSubExpr) { do something }
if (bar without commonSubExpr) { do something }
}
if (bar2) { do something }
... …Run Code Online (Sandbox Code Playgroud) 在下一种情况下声明新变量是否有任何性能成本:
这是一个例子,只是为了证明这一点.
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我有下一个方法:
选项1:
public void MyMethod(Person person)
{
if (person.FirstName.Contains("Ro") || (person.LastName.StartsWith("A") && person.Age > 20))
{
//Do something
}
else if (person.FirstName.Contains("Ko") || (person.LastName.StartsWith("B") && person.Age >= 40))
{
//Do something
}
else if (person.FirstName.Contains("Mo") || (person.LastName.StartsWith("C") && person.Age > 60))
{
//Do something
}
else
{
//Do something
}
}
Run Code Online (Sandbox Code Playgroud)
选项2: …
如果我用 C++CLI/托管 C++ 编写程序,编译器是否会执行任何优化?
我知道对于C#来说,有一些优化是在编译时完成的,其中大多数优化是由JIT完成的。C++CLI 也是如此吗?
类似的问题:对于 C++CLI,我可以做相当于 -O2 标志的操作吗?我已经知道“-c Release”标志,但我不清楚它做了什么样的优化。
谢谢!
编译器是否同样处理下面两种情况,或者情况2是否提供了性能提升,因为x/2不会经常重新评估?我总是假设后者,但如果有人能证实这一点,那将会很棒.
情况1:
double result;
for (int i = 0; i < 10000000; i++) {
result += variables[i] * (x/2);
}
return result;
Run Code Online (Sandbox Code Playgroud)
案例2:
double result;
double xOverTwo = x/2;
for (int i = 0; i < 10000000; i++) {
result += variables[i] * (xOverTwo);
}
return result;
Run Code Online (Sandbox Code Playgroud) 我担心人们总是使用getter-setter模式:
public int MyVariable { get; private set; }
public void SomeFunction(){
MyVariable = 10;
}
Run Code Online (Sandbox Code Playgroud)
据我所知,编译为:
private int myVariable;
public int GetMyVariable(){
return myVariable;
}
private void SetMyVariable(int value){
myVariable = value;
}
public void SomeFunction()
{
SetMyVariable(10);
}
Run Code Online (Sandbox Code Playgroud)
如果频繁使用,它不会影响程序的性能吗?这样做是不是更好:
private int myVariable;
public int MyVariable { get {return myVariable; } }
public void SomeFunction(){
myVariable = 10;
}
Run Code Online (Sandbox Code Playgroud) 我在笔记本电脑上运行了这个,64位Windows 8.1,2.2 Ghz Intel Core i3.代码是在发布模式下编译的,并且在没有附加调试器的情况下运行.
static void Main(string[] args)
{
calcMax(new[] { 1, 2 });
calcMax2(new[] { 1, 2 });
var A = GetArray(200000000);
var stopwatch = new Stopwatch();
stopwatch.Start(); stopwatch.Stop();
GC.Collect();
stopwatch.Reset();
stopwatch.Start();
calcMax(A);
stopwatch.Stop();
Console.WriteLine("caclMax - \t{0}", stopwatch.Elapsed);
GC.Collect();
stopwatch.Reset();
stopwatch.Start();
calcMax2(A);
stopwatch.Stop();
Console.WriteLine("caclMax2 - \t{0}", stopwatch.Elapsed);
Console.ReadKey();
}
static int[] GetArray(int size)
{
var r = new Random(size);
var ret = new int[size];
for (int i = 0; i < size; i++)
{
ret[i] = r.Next(); …Run Code Online (Sandbox Code Playgroud)