我在XNA中闲逛,发现其中的Vector3类是使用公共字段而不是属性.我尝试了一个快速的基准测试,并发现,struct差异非常大(将两个向量组合在一起,1亿次带有2.0s属性和1.4s带字段).对于参考类型,差异似乎并不大,但它存在.
那为什么呢?我知道属性被编译成get_X和set_X方法,这会导致方法调用开销.但是,这些简单的getter/setter是不是总是被JIT内联?我知道你无法保证JIT决定做什么,但肯定这在概率列表中相当高?还有什么将公共领域与机器级别的财产分开?
有一点我一直想知道:自动实现的属性(public int Foo { get; set; })比公共领域"更好"的OO设计?或者更好地说:那两个有什么不同?我知道用反射把它变成一个属性更容易,但其他什么呢?我打赌这两个问题的答案是一回事.
BTW:我使用.NET 3.5 SP1,我相信固定的问题,其中有结构的方法(或方法的结构,我不知道)均未成行,所以这不是它.我认为我至少使用它,它肯定安装但是再次,我使用Vista 64位SP1应该有DX10.1,除了我没有DX10.1 ..
另外:是的,我一直在运行发布版本:)
编辑:我很欣赏的快速解答的家伙,但我指出,我不知道,一个属性访问是一个方法调用,但我不知道为什么,大概是,在林立的方法比直接字段访问速度较慢.
编辑2:所以我创建了另一个struct使用显式GetX()方法(o我怎么不完全错过我的Java时间),并且无论我是否禁用内嵌(通过),都执行相同的操作[MethodImplAttribute(MethodImplOptions.NoInlining)],所以结论:非静态方法显然从未内联,甚至不在结构上.
我认为有异常,JIT可以选择虚拟方法调用.为什么不能在没有继承的结构上发生这种情况,因此方法调用只能指向一种可能的方法,对吧?或者是因为你可以在它上面实现一个接口?
这是一种耻辱,因为它真的会让我考虑在性能关键的东西上使用属性,但使用字段会让我觉得很脏,我不妨写下我在C中做的事情.
编辑3:我发现这篇文章的主题完全相同.他的最终结论是,财产电话确实被优化了.我也可以发誓我已经多次阅读过简单的getter/setter属性会被内联,尽管callvirt在IL中.我疯了吗?
编辑4:Reed Copsey在下面的评论中发布了答案:
Re:Edit3 - 看我更新的评论:我相信这是x86 JIT vs x64 JIT问题.x64中的JIT不够成熟.随着越来越多的64位系统每天上线,我希望MS能够迅速提高. - 里德·科普塞
我回答他的回答:
谢谢,这就是答案!我尝试强制x86构建,所有方法都同样快,并且比x64快得多.实际上这对我来说非常令人震惊,我不知道我是在64位操作系统上生活在石器时代.我会在你的答案中包含你的评论,以便更好. - 朱利安
感谢大家!
我正在阅读"清洁代码"这本书,并且正在努力解决这个问题.在讨论对象和数据结构时,它指出以下内容:
所以,我从中获得的是我不应该在我的对象上有任何公共属性,我应该只有对属性执行操作的方法.如果我确实需要访问属性,它们应该在数据结构上,可以从我对象上的方法返回?使用这种方法,似乎我需要为我的对象上的Height属性使用GetHeight()和SetHeight()方法,而不是仅使用属性的get和set.
也许我不明白究竟是什么建议,但这是我对" 对象隐藏他们的数据 "的理解.如果你能帮助我理解这一点,我将非常感激!
提前致谢!
C#内联访问属性吗?我知道内联的JIT有32字节(指令?)限制,但它是内联属性还是只是纯方法调用?
Windows服务在调试版本和发布版本之间获得多少性能提升(如果有的话)以及为什么?
我正在研究摄像机拍摄的1000万像素图像.
目的是在矩阵(二维阵列)中记录每个像素的灰度值.
我第一次使用GetPixel,但它需要25秒才能完成.现在我使用Lockbits但是它需要10秒,如果我不将结果保存在文本文件中则需要3秒.
我的导师说他们不需要注册结果,但3秒仍然太慢.我在我的程序中做错了什么,或者我的应用程序有比Lockbits更快的东西吗?
这是我的代码:
public void ExtractMatrix()
{
Bitmap bmpPicture = new Bitmap(nameNumber + ".bmp");
int[,] GRAY = new int[3840, 2748]; //Matrix with "grayscales" in INTeger values
unsafe
{
//create an empty bitmap the same size as original
Bitmap bmp = new Bitmap(bmpPicture.Width, bmpPicture.Height);
//lock the original bitmap in memory
BitmapData originalData = bmpPicture.LockBits(
new Rectangle(0, 0, bmpPicture.Width, bmpPicture.Height),
ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
//lock the new bitmap in memory
BitmapData newData = bmp.LockBits(
new Rectangle(0, 0, bmpPicture.Width, bmpPicture.Height),
ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
//set …Run Code Online (Sandbox Code Playgroud) 假设我们有一个带有大量冗余访问器的生成类.它们只是访问者,它们不是字段.它们不会被称为任何地方.他们只是坐在那里多余和丑陋.
例如:
public class ContrivedExample
{
public int ThisOneIsUsed { get; set; }
public int ThisOneIsNeverCalled0 { get { /* Large amounts of logic go here, but is never called. */ } }
public int ThisOneIsNeverCalled1 { get { /* Large amounts of logic go here, but is never called. */ } }
public int ThisOneIsNeverCalled2 { get { /* Large amounts of logic go here, but is never called. */ } }
//...
public int ThisOneIsNeverCalled99 { get { …Run Code Online (Sandbox Code Playgroud) 我正在写一个简单的回合制RPG系统.我有一个BattleScreen类来处理绘图...屏幕.事情是,它必须知道关于我Player班级的几乎所有事情.它Name,HP值,MP值,JobName,Level,Experience,Moneyetc.etc.etc.为了把它写在屏幕上.我的Draw()方法最终会从中抽取几乎所有变量Player,并且它要求我在Player公共场合制作几乎所有的东西
这让我相信让这个Player类自己画出来更好一点,但最后我得到了需要调用的多个Draw()方法BattleScreen.如果Player是主要播放器(具有所有数据和名称)的情况下的绘制方法,以及它在场边(只有精灵和HP/MP可见)的一个绘制方法,以及其他屏幕的其他方法.
两种方式都感觉很蠢.
这两种方式中的任何一种都被认为是"正常"吗?有没有更好的方法来设计它?
c# ×7
properties ×3
.net ×2
abstraction ×1
clr ×1
debugging ×1
lockbits ×1
object ×1
oop ×1
optimization ×1
overhead ×1
release ×1
struct ×1
xna-4.0 ×1