C# 如果我给一个类添加更多的方法,每个实例会占用更多的空间吗?
作为一名程序员,您总是可以选择向类添加方法,或者创建将该对象的类实例作为参数的相同方法 一种方法是:C# 如果我给一个类添加更多的方法,每个实例会占用更多的空间吗?,c#,performance,C#,Performance,作为一名程序员,您总是可以选择向类添加方法,或者创建将该对象的类实例作为参数的相同方法 一种方法是: List<Car> Oldtimers = new List<Car>(); class Car { int speed; int size; public bool IsBig(){ return size >5; } public bool isFast(){ return speed > 1
List<Car> Oldtimers = new List<Car>();
class Car {
int speed;
int size;
public bool IsBig(){
return size >5;
}
public bool isFast(){
return speed > 120;
}
}
List Oldtimers=new List();
类汽车{
整数速度;
整数大小;
公共图书馆很大{
返回大小>5;
}
公共bool isFast(){
返回速度>120;
}
}
或者你也可以这样节省空间
class CarCollection {
List<Car2> Supercars = new List<Car2>();
class Car2{
public int speed;
public int size;
}
bool IsBig(Car2 car){
return car.size > 5
}
bool isFast(Car2 car){
return car.speed > 120;
}
}
类CarCollection{
List Supercars=newlist();
类Car2{
公共交通速度;
公共整数大小;
}
bool IsBig(Car2车){
返回车。尺寸>5
}
布尔伊斯法斯特(Car2轿车){
返回车速度>120;
}
}
由于没有附加方法,Car2实例现在实际占用的空间是否比Car少?哪个列表更好?字节码之间有差异吗
我还想知道标准是什么,或者是否存在一些我没有看到的性能问题
谢谢你的帮助
Car2实例现在是否比Car实例占用更少的空间,b
没有
每个实例都有一个指向其类型的指针,以及附加的一些其他信息。但即使使用虚拟方法,这种开销也是固定的
只有字段会占用实例内部的空间。如果确实需要为每个实例保存字节,则可以切换到存储数据的结构列表,并具有访问数据的管理器类,如示例中所示。棘手的部分是当汽车被拆除时。您还可以考虑使用较小的数字类型,如short或byte。以下是一个例子:
public struct CarHandle
{
internal int m_id;
internal CarHandle(int id)
{
m_id = id;
}
public int ID { get { return m_id; } }
}
public class CarManager
{
private struct CarData
{
public int Speed;
public int Size;
}
private List<CarData> m_cars = new List<CarData>();
private List<int> m_removedCars = new List<int>();
public CarHandle CreateCar(int speed, int size)
{
var carData = new CarData() { Speed = speed, Size = size };
// see if there is an empty slot we can use
if (m_removedCars.Count > 0)
{
int ix = m_removedCars[m_removedCars.Count - 1];
m_removedCars.RemoveAt(m_removedCars.Count - 1);
m_cars[ix] = carData;
return new CarHandle(ix);
}
else
{
m_cars.Add(carData);
return new CarHandle(m_cars.Count-1);
}
}
public void RemoveCar(ref CarHandle handle)
{
if (m_cars.Count > handle.ID && m_cars[handle.ID].Size != -1)
{
// remove from list if it is the last car in list
if (handle.ID == m_cars.Count - 1)
{
m_cars.RemoveAt(m_cars.Count - 1);
}
else
{
// if we remove this item from the list, it would invalidate
// all handles after this index, so we just remember that we
// can reuse this slot
m_removedCars.Add(handle.ID);
m_cars[handle.ID] = new CarData() { Size = -1, Speed = -1 };
}
}
// invalidate the handle so it cannot be used again
handle.m_id = -1;
}
public int GetSize(CarHandle handle)
{
// TODO: add error checking!
return m_cars[handle.ID].Size;
}
}
class Program
{
static void Main(string[] args)
{
CarManager manager = new CarManager();
var car1 = manager.CreateCar(10, 20);
var s1 = manager.GetSize(car1);
System.Diagnostics.Debug.Assert(s1 == 20);
var car2 = manager.CreateCar(30, 40);
var s2 = manager.GetSize(car2);
System.Diagnostics.Debug.Assert(s2 == 40);
manager.RemoveCar(ref car1);
System.Diagnostics.Debug.Assert(car1.ID == -1);
s2 = manager.GetSize(car2);
var car3 = manager.CreateCar(50, 60);
var s3 = manager.GetSize(car3);
System.Diagnostics.Debug.Assert(s3 == 60);
}
}
公共结构CarHandle
{
内部int m_id;
内部车把手(内部id)
{
m_id=id;
}
公共int ID{get{return m_ID;}}
}
公共类管理器
{
私有结构卡数据
{
公共交通速度;
公共整数大小;
}
私人列表m_车=新列表();
私有列表m_removedCars=新列表();
公共车把手CreateCar(整数速度,整数大小)
{
var carData=new carData(){Speed=Speed,Size=Size};
//看看是否有空的插槽可以使用
如果(m_removedCars.Count>0)
{
int ix=m_removedCars[m_removedCars.Count-1];
m_removedCars.RemoveAt(m_removedCars.Count-1);
m_cars[ix]=卡数据;
归还新车把(九);
}
其他的
{
m_cars.Add(carData);
归还新车把(m_车。计数-1);
}
}
公共无效删除卡(参考CarHandle handle)
{
如果(m_cars.Count>handle.ID&&m_cars[handle.ID].Size!=-1)
{
//如果是列表中的最后一辆车,则从列表中删除
if(handle.ID==m_cars.Count-1)
{
m_cars.RemoveAt(m_cars.Count-1);
}
其他的
{
//如果我们从列表中删除此项,它将无效
//所有句柄都在这个索引之后,所以我们只需记住
//你能重复使用这个插槽吗
m_removedCars.Add(handle.ID);
m_cars[handle.ID]=new CarData(){Size=-1,Speed=-1};
}
}
//使句柄无效,使其无法再次使用
handle.m_id=-1;
}
public int GetSize(CarHandle句柄)
{
//TODO:添加错误检查!
返回m_车[handle.ID]。大小;
}
}
班级计划
{
静态void Main(字符串[]参数)
{
CarManager manager=新的CarManager();
var car1=manager.CreateCar(10,20);
var s1=manager.GetSize(car1);
System.Diagnostics.Debug.Assert(s1==20);
var car2=manager.CreateCar(30,40);
var s2=manager.GetSize(car2);
System.Diagnostics.Debug.Assert(s2==40);
RemoveCar经理(参考car1);
System.Diagnostics.Debug.Assert(car1.ID==-1);
s2=manager.GetSize(car2);
var car3=manager.CreateCar(50,60);
var s3=manager.GetSize(car3);
System.Diagnostics.Debug.Assert(s3==60);
}
}
感谢您的快速回复!使概念优化不是一个好主意。对类和类型进行清晰易懂的设计。如果将方法放在类之外会使其实例占用更少的空间,除了清晰性之外没有其他缺点,那么C#编译器就可以做到这一点,即使在逻辑上将方法放在类内,因为它不需要保持清晰性。唯一不可能的方法是在运行时将方法附加并重新附加到实例,这是不可能的。(通常——dynamic
是另一头野兽。)因此,即使从纯理论的角度来看,你也可以预言,在任何合理的世界里,答案都应该是“不”。(尽管世界往往是不合理的。)