抑或是现在的其他方式?
从我所听到的也有一些在C#中被证明是比C ++快的地区,但我从来没有胆量由我自己来测试它。
以为任何你能详细解释这些差异或点我对这些信息的正确的地方。
抑或是现在的其他方式?
从我所听到的也有一些在C#中被证明是比C ++快的地区,但我从来没有胆量由我自己来测试它。
以为任何你能详细解释这些差异或点我对这些信息的正确的地方。
没有严格的原因,如C#或Java字节码为基础的语言,有一个JIT不能以最快的速度C ++代码。 然而C ++代码使用了很长时间是显著更快,而且今天仍然在许多情况下。 这主要是由于被复杂更先进的JIT优化来实现,而真的很酷的人现在才刚刚到达现在。
所以C ++也比较快,在很多情况下。 但这只是答案的一部分。 的情况下,C ++实际上是更快的,是高度优化的程序,其中专业程序员彻底优化了地狱的代码。 这不仅非常耗时的(因而昂贵的),但通常也导致因过度优化的错误。
在另一方面,在解释型语言代码获取在运行时(CLR .NET或Java VM)的后续版本速度更快,无需你做任何事情。 这里面有很多有用的优化的JIT编译器可以做到这一点与指针的语言是根本不可能的。 此外,有些人认为垃圾收集一般应以最快的速度或更快手动内存管理,并且在许多情况下,它是。 你通常可以实现,实现这一切在C ++或C,但它要复杂得多,而且容易出错。
正如高德纳说,“过早的优化是所有罪恶的根源。” 如果你真的肯定知道你的应用程序将主要由非常性能的关键算法,那它就会成为瓶颈,它肯定要在C ++更快,你确信C ++不会与其他冲突要求,去C ++。 在任何其他情况下,集中精力先在任何一种语言西装正确地实现您的应用程序,你最好的,然后找到性能瓶颈,如果它运行速度太慢,然后思考如何优化代码。 在最坏的情况下,你可能需要通过外部函数接口来调用出来的C代码,所以你还是得写关键部件在较低的水平语言的能力。
请记住,这是比较容易优化正确的程序,但更难纠正优化程序。
给人的速度优势,实际百分比是不可能的,它在很大程度上取决于你的代码。 在许多情况下,编程语言的实现甚至不是瓶颈。 采取在基准http://benchmarksgame.alioth.debian.org/持怀疑态度的一个很大的,因为这在很大程度上考验算术编码,这是最有可能不相似的代码在所有。
C#未必会更快,但它会让你/我更快。 这是为我做的最重要的措施。 :)
这五个橘子快。 或者说:不可能有(正确的)毯的答案。 C ++是一种静态编译语言(但后来,有轮廓引导优化,太),通过JIT编译器的帮助C#运行。 有这么多不同的是像“快多少”不能回答,甚至没有给予量级。
我打算通过与接受(和精心upvoted)回答这个问题时指出的部分不同意开始:
其实有很多原因实时编译的代码运行速度比正常优化的C ++(或其他语言不运行时开销)计划 ,包括慢的原因 :
在运行时花费在JITting代码的计算周期被定义为在程序执行无法使用。
在抖动任何热的路径将与您的CPU中的指令和数据缓存代码竞争。 我们知道,当涉及到性能和本地语言如C ++没有这种类型的争夺,根据定义缓存占主导地位。
运行时优化的时间预算必然比的更多的约束编译时优化器(如另一个评论指出)
底线:最终,你几乎肯定能在C创建一个更快的实现++比你在C#中能 。
现在,随着中说, 快多少真的是无法量化,因为有太多的变数:任务,问题域,硬件实现的质量,以及许多其他因素。 你必须对你的情况进行测试,以确定在性能上的差异,然后再决定是否值得的额外工作量和复杂性。
这是一个非常漫长和复杂的话题,但我觉得这是值得一提的完整性考虑的是C#的运行时间优化非常出色,并且能够执行在运行时是根本不能用于C ++,其编译时(某些动态优化静态)优化。 即使有这样的优势,通常仍深深的本机应用程序的法院,但动态优化是上面给出的“ 几乎可以肯定”资格的原因。
-
在相对性能方面,我也受到了附图和讨论,我在一些其他的答案看到不安,所以我想我会附和,并在同一时间,为我上面的发言一定的支撑。
问题与基准的巨大的部分是你可以不写C ++代码,如果你正在写C#,并期望得到代表性的结果(例如,在C ++中进行数千内存分配将会给你可怕的数字。)
相反,我写的稍微更地道的C ++代码,并提供对C#代码@Wiory比较。 我对C ++代码所做的两个主要变化是:
1)可使用载体::储备()
2)平坦化的2D阵列至1d以达到更好的高速缓存局部性(连续块)
C#(.NET 4.6.1)
private static void TestArray()
{
const int rows = 5000;
const int columns = 9000;
DateTime t1 = System.DateTime.Now;
double[][] arr = new double[rows][];
for (int i = 0; i < rows; i++)
arr[i] = new double[columns];
DateTime t2 = System.DateTime.Now;
Console.WriteLine(t2 - t1);
t1 = System.DateTime.Now;
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
arr[i][j] = i;
t2 = System.DateTime.Now;
Console.WriteLine(t2 - t1);
}
运行时间(释放):初始化:124ms,填写:165ms的
C ++ 14(锵V3.8 / C2)
#include <iostream>
#include <vector>
auto TestSuite::ColMajorArray()
{
constexpr size_t ROWS = 5000;
constexpr size_t COLS = 9000;
auto initStart = std::chrono::steady_clock::now();
auto arr = std::vector<double>();
arr.reserve(ROWS * COLS);
auto initFinish = std::chrono::steady_clock::now();
auto initTime = std::chrono::duration_cast<std::chrono::microseconds>(initFinish - initStart);
auto fillStart = std::chrono::steady_clock::now();
for(auto i = 0, r = 0; r < ROWS; ++r)
{
for (auto c = 0; c < COLS; ++c)
{
arr[i++] = static_cast<double>(r * c);
}
}
auto fillFinish = std::chrono::steady_clock::now();
auto fillTime = std::chrono::duration_cast<std::chrono::milliseconds>(fillFinish - fillStart);
return std::make_pair(initTime, fillTime);
}
运行时间(释放):初始化:398μs(是的,这是微秒),填写:152ms
意见
改变C#实现到相同的一维数组执行产生初始化:40毫秒,补:171ms,共计:211ms(C ++仍然几乎快40%)。
它是更难设计和编写C“快” ++代码比它写在任何语言的“常规”代码。
这是(也许)惊人地容易在C来到达表现不佳++; 我们看到了无保留向量性能。 还有很多类似这样的陷阱。
当你考虑所有在运行时是怎么回事C#的性能是相当惊人的。 而性能是比较容易进入。
更传闻数据进行比较,C ++和C#的性能: https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=gpp&lang2=csharpcore
底线是,C ++为您提供了性能更多的控制。 你想使用指针? 参考? 栈内存? 堆? 动态多态性或消除与静态多态性的虚函数表的运行时开销(通过模板/ CRTP)? 在C ++中,你必须......呃, 去使所有这些选择(及以上)自己,最好让你的解决方案最满足你解决这一问题。
问问自己,如果你真的想要或需要的是控制,因为即使上面的简单的例子,你可以看到,虽然在性能上显著的改善,这需要更深层次的投资进入。
根据我的经验(我已经做了很多用两种语言),使用C#的主要问题相比,C ++是高内存消耗,而且我还没有找到控制它的好方法。 这是内存的消耗,将.NET软件最终会放慢。
另一个因素是JIT编译器不能承受太多的时间做先进的优化,因为它运行在运行时,如果花费太多时间的最终用户会注意到它。 在另一方面,C ++编译器都需要在编译的时候做优化的时候。 这个因素是要比内存消耗少显著,恕我直言。
当多晶型的决定可以在编译时被预先确定时,其中C ++仍具有上风(并将,几年来)一个特定的场景。
一般来说,封装和推迟的决策是一件好事,因为它使代码更动态,更容易适应不断变化的需求,更容易作为一个框架来使用。 这就是为什么在C#中的面向对象编程是非常有成效的,它可以在术语“泛化”一概而论。 不幸的是,这种特殊的概括来自于在运行时的代价。
通常情况下,这个成本是不显着,但在一些应用中虚方法调用和对象创建的开销可以有所作为的(尤其是因为虚拟方法防止其他优化,如方法调用内联)。 这是C ++有巨大的优势,因为你可以使用模板来实现不同类型的概括这对运行时没有任何影响,但并不一定比任何OOP少多态。 事实上,所有构成OOP的机制可以仅使用模板技术来模拟和编译时间分辨率。
在这种情况下(诚然,他们常常被局限于特殊的问题域),C ++胜对C#和可比的语言。
C ++(或为此事C)让您对数据结构进行细粒度的控制。 如果要位玩弄你有这样的选择。 大型管理Java或.NET应用程序(OWB, Visual Studio 2005中 )使用Java / .NET库的内部数据结构随身携带行李。 我已经使用了400 MB的RAM和BIDS为立方体或看到OWB设计师会话ETL设计进入MB的100的为好。
在可预测的工作负载(如重复的过程多次大部分测试)一个JIT可以得到你所优化的不够好,没有实际的区别代码。
IMO在大型应用程序的区别是没有这么多的JIT为代码本身使用的数据结构。 当一个应用程序内存沉重,你会得到较少高效的高速缓存的使用。 在现代CPU高速缓存未命中是相当昂贵的。 其中C或C ++真正赢得在这里你可以优化你的数据结构的使用与CPU缓存发挥很好。
用于图形的标准C#Graphics类是这样慢于GDI通过C / C ++访问。 我知道这无关的语言本身,更与总.NET平台,但图形是什么是提供给开发者的GDI替换,其表现是如此糟糕,我不会甚至不敢做图形用它。
我们有我们用看图形库的速度有多快一个简单的基准,那就是简单地绘制在一个窗口中随机线。 C ++ / GDI还是活泼与10000线,而C#/图形有困难的,实时的做1000。
垃圾收集是主要的原因Java的#不能用于实时系统。
什么时候会发生GC?
这需要多长时间?
这是不确定性。
我们不得不决定是否C#在性能堪比C ++,我写了一些测试程序(使用Visual Studio 2005为这两种语言)。 原来,没有垃圾收集和仅考虑语言(不是框架)C#有基本相同的性能,C ++。 内存分配方式在C#比在C ++更快和C#具有确定性轻微边缘时数据大小超出了高速缓存线边界增加。 然而,这一切不得不最终支付和存在的不确定性性能命中为C#,由于垃圾收集形成巨大的成本。
像往常一样,这取决于应用。 存在这样的情况C#是可以忽略的程度可能较慢,以及其他情况下,C ++是快5倍或10倍,尤其是在操作可被容易地SIMD'd例。
我知道这是不是你问的是什么,但是C#往往快于C ++,这是在商业环境巨额奖金来写 。
C / C ++可在存在或大阵列或重循环/迭代过(任意大小的)阵列方案好得多的执行。 这是显卡一般都在C / C ++快得多,因为重数组操作背后几乎所有的图形操作的原因。 .NET是由于所有的安全检查阵列索引操作相当慢,并且这对于多维数组(是的,矩形C#阵列不是参差不齐C#阵列更慢),尤其如此。
C / C ++的奖金,如果你直接与指针坚持,避免加速,最为显着std::vector
和其他高层次的容器,以及inline
每一个细小的功能成为可能。 尽可能使用老派的阵列。 是的,你将需要更多的代码来完成你在Java或C#做同样的事情,你避免高层次的容器。 如果你需要一个动态大小的数组,你只需要记住配对new T[]
与相应delete[]
语句(或使用std::unique_ptr
):表示该价格为额外的速度是你必须更仔细地编码。 但是作为交换,你要摆脱托管内存/垃圾收集的开销,这可以很容易地在Java和.NET大量面向对象的程序的执行时间的20%或更多的自己,以及那些大规模的管理存储器阵列的索引的成本。 C ++的应用也可以受益于在某些特定的情况下一些漂亮的编译器开关。
我在C,C ++,Java和C#的编程专家。 我最近有个别情况下在后3种语言来实现完全相同的算法程序。 该方案有很多数学和多维数组操作。 我巨资在所有3种语言优化这一点。 结果是典型的我通常看到的不太严格的比较:Java的约1.3倍的比C#快(大多数的JVM比CLR更加优化),以及C ++原始指针的版本排在约2.1倍比C#快。 需要注意的是,C#程序只使用安全的代码,这是我的看法,你可能会使用C中的前以及编码它++ unsafe
关键字。
为了避免有人认为我对C#的东西,我会说,C#可能是我最喜欢的语言关。 这是迄今为止我所遇到的最合乎逻辑的,直观,快速发展的语言。 我做我在C#中的所有原型。 C#语言对Java有许多小的,细微的优势(是的,我知道微软不得不通过后期进入游戏,可以说是抄袭Java来修复许多Java的缺点的机会)。 吐司Java的Calendar
类人? 如果微软曾经花真功夫,以优化CLR和.NET抖动,C#可能严重接管。 我诚实地惊讶,他们尚未-他们做了这么多的事情就在C#语言,为什么不重量级的编译器优化跟进? 也许,如果我们所有乞讨。
>从我所听到的...
你的困难似乎是在决定你听说过是否是可信的,而当你试图评估本网站的答复是困难只会重复。
你将如何决定,如果事情的人说这里比您最初听到或多或少可信吗?
一种方法是索要证据 。
当有人声称“有一些在C#中被证明是比C更快领域++” 问他们为什么 ,他们说 ,让他们向你展示的测量,要求他们向您展示方案。 有时,他们会简单地犯了一个错误。 有时候,你会发现,他们只是表达意见,而不是共享的东西,他们可以展示是真实的。
通常,信息和意见会是什么人在要求混合起来,你必须尝试理清哪个是哪个。 例如,从这个论坛的答复:
“就拿基准,而http://shootout.alioth.debian.org/持怀疑态度的一个很大的,因为这在很大程度上考验算术编码,这是最有可能不相似的代码在所有。”
问问自己,如果你真的了解什么“这些主要是测试算术码”的意思,然后问自己,如果笔者实际显示你,他的说法是真实的。
“这是一个相当无用的测试,因为它实际上取决于如何做好各个程序进行了优化;我已经成功通过4-6次或更多,以加快他们中的一些,这就很清楚,未优化的方案之间的比较是相当愚蠢。”
问问自己,作者是否实际上已经显示你他成功地“通过4-6次或更多次加速一些人” - 这是一个简单的要求,使!
.NET语言可以以最快的速度C ++代码,甚至更快, 但C ++代码将有较恒定的吞吐量 .NET运行库已暂停GC ,即使它是关于它的停顿非常聪明。
所以,如果你有一个具有一贯没有任何停顿跑得快一些代码,.NET会在某个时候引入延迟,即使你非常小心运行GC。
关于“embarassingly平行”的问题,采用Intel TBB和OpenMP基于C ++时我已与用C#和TPL做过类似的(纯数学)问题观察到大致10倍的性能提升。 SIMD是一个领域,C#无法抗衡,但我也得到了TPL有一个相当大的开销的印象。
这就是说,我只用C ++的,我知道我将能够多线程并迅速得到结果的性能关键任务。 对于一切,C#(偶尔F#)就好了。
这是没有真正明确的答案非常模糊的问题。
例如; 我宁愿播放用C ++创建比C#的3D游戏,因为性能肯定是好多了。 (我知道XNA等,但说到接近真实的东西没办法)。
在另一方面,如前面所述; 你应该在,让你做你想做的迅速语言开发,然后在必要时优化。
从理论上讲,对于长时间运行的服务器类型的应用程序,JIT编译的语言能够成为比本地编译对应快得多 。 由于JIT编译语言通常首先编译成一个相当低级的中间语言,您可以直接在编译的时候做了很多的高级优化的反正。 最大的优势来自于该JIT可以继续重新编译在运行的代码段,因为它得到关于如何应用程序正在使用越来越多的数据。 它可以为您安排最常见的代码路径,允许分支预测到尽可能多地取得成功。 它可以重新安排单独的代码块通常被称为在一起,让他们无论是在高速缓存中。 它可以花更多的精力优化内部循环。
我怀疑这是由.NET或任何的JRE来完成,但它正在研究中回来时,我在大学,所以很快就认为这些类的东西可能会发现他们的方式到现实世界在某些时候它不是不合理。
这需要大量的内存访问,例如应用程序。 图像处理通常是最好写在非托管环境中(C ++)比管理(C#)。 与指针算术优化内部循环是以具有在C ++控制容易得多。 在C#中,你可能需要求助于不安全的代码,甚至可以接近相同的性能。
我测试vector
中的C ++和C#等效- List
和简单的2D阵列。
我使用Visual C#/ C ++ 2010速成版。 这两个项目都是简单的控制台应用程序,我已经在标准(没有自定义设置)发布和调试模式下测试它们。 C#名单上的我的电脑运行速度更快,数组初始化也是在C#中更快,数学运算速度较慢。
我使用的是英特尔酷睿2 P8600@2.4GHz,C# - .NET 4.0。
我知道,向量执行比C#列表中的不同,但我只是想测试我会用它来存储我的对象集合(和能够使用索引访问)。
当然,你需要清除内存(假设每次使用的new
),但我想保持代码的简洁。
C ++向量测试 :
static void TestVector()
{
clock_t start,finish;
start=clock();
vector<vector<double>> myList=vector<vector<double>>();
int i=0;
for( i=0; i<500; i++)
{
myList.push_back(vector<double>());
for(int j=0;j<50000;j++)
myList[i].push_back(j+i);
}
finish=clock();
cout<<(finish-start)<<endl;
cout<<(double(finish - start)/CLOCKS_PER_SEC);
}
C#列表测试:
private static void TestVector()
{
DateTime t1 = System.DateTime.Now;
List<List<double>> myList = new List<List<double>>();
int i = 0;
for (i = 0; i < 500; i++)
{
myList.Add(new List<double>());
for (int j = 0; j < 50000; j++)
myList[i].Add(j *i);
}
DateTime t2 = System.DateTime.Now;
Console.WriteLine(t2 - t1);
}
C ++ -数组:
static void TestArray()
{
cout << "Normal array test:" << endl;
const int rows = 5000;
const int columns = 9000;
clock_t start, finish;
start = clock();
double** arr = new double*[rows];
for (int i = 0; i < rows; i++)
arr[i] = new double[columns];
finish = clock();
cout << (finish - start) << endl;
start = clock();
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
arr[i][j] = i * j;
finish = clock();
cout << (finish - start) << endl;
}
C# -数组:
private static void TestArray()
{
const int rows = 5000;
const int columns = 9000;
DateTime t1 = System.DateTime.Now;
double[][] arr = new double[rows][];
for (int i = 0; i < rows; i++)
arr[i] = new double[columns];
DateTime t2 = System.DateTime.Now;
Console.WriteLine(t2 - t1);
t1 = System.DateTime.Now;
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
arr[i][j] = i * j;
t2 = System.DateTime.Now;
Console.WriteLine(t2 - t1);
}
时间:(发布/调试)
C ++
(是的,13秒,我总是有在调试模式列表/向量的问题。)
C#:
这得看情况。 如果字节码转换成机器代码(而不仅仅是JIT)(我的意思是,如果你执行程序),如果你的程序使用了很多的分配/释放操作可能会更快,因为GC算法只需要一个通(理论上)通过整个存储器一次,但正常的malloc / realloc的/自由C / C ++调用导致在每次调用的开销(呼叫开销,数据结构的开销,高速缓存未命中;))。
因此,它在理论上是可能的(也可用于其他GC语言)。
我实在不明白的不是极端不利能够使用元编程与C#的大多数应用程序,因为大多数程序员不无论如何使用它。
另一大优势是,SQL,像LINQ的“扩展”,提供了编译器优化到数据库的调用(换句话说,这里被称为内联函数编译器可以编译整个LINQ到一个“斑点”二进制或机会为您的使用进行了优化,但我猜测这里)。
我想有运行速度快,以及用C#编写的应用程序,因为有快速运行多个C ++编写的应用程序(以及C ++只是旧的......并采取UNIX太...)
- 这个问题的确是 - 那是什么东西,用户和开发者都在抱怨......
那么,恕我直言,在C#的情况下,我们有非常舒适的用户界面,图书馆的非常漂亮的层次和CLI的整个界面系统。 如果是C ++而言,我们有模板,ATL,COM,MFC和整个家当alreadyc编写和运行的代码,比如OpenGL,DirectX和等等......开发商抱怨indeterminably上升GC在C#的情况下调用(指程序运行速度快,在一秒钟 - 砰它卡住了!)。
需要编写C#非常简单和快速的代码(不要忘了,也增加了失误的机会在C ++的情况下,开发商抱怨的内存泄漏, - 指迷恋,DLL的调用之间,以及“DLL地狱”的 - 问题由较新的支持和更换库...
我想更多的技能,你就必须在编程语言,更多的质量(和速度)会列出您的软件。
我会这样说:程序员谁写的更快的代码,是谁是更明智的是什么使当前机器走的快,而且顺带他们也是谁使用合适的工具,允许精确的低层次性和确定性的那些的那些优化技术。 由于这些原因,这些人都是谁使用C / C ++而不是C#的人。 我会去尽可能说明这是一个事实。
>毕竟,答案必须是某个地方,是不是? :)
嗯,没有。
正如一些答复指出, 问题的方式,邀请问题的反应,而不是答案下指定 。 仅举方式:
然后哪些程序? 哪台机器? 哪个操作系统? 哪个数据集?
如果我没有记错的话,C#模板在运行时确定。 这必须是慢于编译C ++的时间模板。
而当你在这么多的人,还有,做缺乏安全性提到的所有其他的编译时优化走,确实,意味着更多的速度...
我会说C ++是在原始的速度和最小的内存消耗方面的不二之选。 但是,这也转化为更多的时间开发的代码,并确保你没有内存泄漏或导致任何空指针异常。
判决:
C#:更快的开发,运行速度较慢
C ++:发展缓慢,更快地运行。
这真的取决于你想在你的代码完成的任务。 我听说这是都市传说的只是东西有VB.NET,C#之间的性能差异和托管C ++。 然而,我发现,至少在字符串比较,即托管C ++击败脱裤子的C#,这反过来又击败脱裤子VB.NET的。
我已经没有做过的算法语言之间复杂的任何详尽的比较方式。 我也只是在使用每种语言的默认设置。 在VB.NET我使用的设置要求的变量声明等。这是我使用托管C ++代码:(正如你所看到的,这个代码非常简单)。 我与.NET 4.6.2运行其他语言一样在Visual Studio 2013
#include "stdafx.h"
using namespace System;
using namespace System::Diagnostics;
bool EqualMe(String^ first, String^ second)
{
return first->Equals(second);
}
int main(array<String ^> ^args)
{
Stopwatch^ sw = gcnew Stopwatch();
sw->Start();
for (int i = 0; i < 100000; i++)
{
EqualMe(L"one", L"two");
}
sw->Stop();
Console::WriteLine(sw->ElapsedTicks);
return 0;
}
受此启发,我做了一个快速测试,在大部分的程序所需要的公用指令的60%。
下面是C#代码:
for (int i=0; i<1000; i++)
{
StreamReader str = new StreamReader("file.csv");
StreamWriter stw = new StreamWriter("examp.csv");
string strL = "";
while((strL = str.ReadLine()) != null)
{
ArrayList al = new ArrayList();
string[] strline = strL.Split(',');
al.AddRange(strline);
foreach(string str1 in strline)
{
stw.Write(str1 + ",");
}
stw.Write("\n");
}
str.Close();
stw.Close();
}
字符串数组和ArrayList特意用于包括那些指令。
这里的C ++代码:
for (int i = 0; i<1000; i++)
{
std::fstream file("file.csv", ios::in);
if (!file.is_open())
{
std::cout << "File not found!\n";
return 1;
}
ofstream myfile;
myfile.open ("example.txt");
std::string csvLine;
while (std::getline(file, csvLine))
{
std::istringstream csvStream(csvLine);
std::vector csvColumn;
std::string csvElement;
while( std::getline(csvStream, csvElement, ‘,’) )
{
csvColumn.push_back(csvElement);
}
for (std::vector::iterator j = csvColumn.begin(); j != csvColumn.end(); ++j)
{
myfile << *j << ", ";
}
csvColumn.clear();
csvElement.clear();
csvLine.clear();
myfile << "\n";
}
myfile.close();
file.close();
}
我使用的输入文件大小为40 KB。
而这里的结果 -
哦,不过这是在Linux上...用C#上运行的单 ...和C ++与G ++。
OK,这就是我在Windows上得到了- Visual Studio 2003中 :