简体   繁体   English

可变结构作为成员变量以提高序列化/JSON 生成的性能

[英]Mutable structs as member variables for performance in Serialization/JSON Generation

I tried to read up why mutable structs are evil, which was previously posted here.我试图阅读为什么可变结构是邪恶的,这是之前发布在这里的。

Why are mutable structs “evil”? 为什么可变结构是“邪恶的”?

But my post is more about a specific scenario.但我的帖子更多的是关于一个特定的场景。

Given following scenario鉴于以下场景

I want to have a small, fast to serialize "data class", to speed up my Save/Load Mechanism我想要一个小而快速的序列化“数据类”,以加快我的保存/加载机制

I have a Player class which I can use inside the Unity Editor.我有一个可以在 Unity 编辑器中使用的 Player 类。 This Player class has a member variable called "Stats" which is a struct.这个 Player 类有一个名为“Stats”的成员变量,它是一个结构体。

public class Player : MonoBehaviour
{
    public PlayerStats Stats;
}

Below you can see the System.Serializable struct I am using as "data class"您可以在下面看到我用作“数据类”的 System.Serializable 结构

[System.Serializable]
public struct PlayerStats
{
   public uint Speed;

   public void SetSpeed(uint speed)
   {
      this.Speed = Math.clamp(speed, Rules.MinSpeed, Rules.MaxSpeed);
   }
}

So later on to prevent the overhead i am experiencing from serializing a MonoBehaviour i use所以稍后为了防止我在序列化我使用的 MonoBehaviour 时遇到的开销

JsonUtility.ToJson(player.Stats)

Now my question is, if I use SetSpeed anywhere in the code to modify the Value inside the struct现在我的问题是,如果我在代码中的任何地方使用 SetSpeed 来修改结构内的值

player.Stats.SetSpeed(3);

does this now lead to copies of the struct being made, because the value is being modified?这是否会导致生成结构的副本,因为值正在被修改?

Any clarifications would be great.任何澄清都会很棒。

No, changing the value of field in a struct does not cause a copy to be made.不,更改结构中字段的值不会导致复制。 The copies are made when the structure is assigned to another variable.当将结构分配给另一个变量时,会生成副本。 SetSpeed is a member function and has no struct parameter so won't cause a copy to be made. SetSpeed 是一个成员函数,没有结构参数,因此不会导致复制。

For example, you call a method here:例如,您在这里调用一个方法:

JsonUtility.ToJson(playerDTO.Stats);

This will cause a copy of the structure to be made and assigned to the parameter inside the function, regardless of whether you later call SetSpeed.这将导致创建结构的副本并将其分配给函数内部的参数,无论您稍后是否调用 SetSpeed。 Any changes you make to playerDTO after this call won't change the local copy inside the ToJson function.在此调用之后您对playerDTO任何更改都不会更改 ToJson 函数内的本地副本。

Perhaps in your case this isn't a concern (as in many cases).也许在您的情况下,这不是问题(在许多情况下)。 In other cases people could use a struct when actually they want to pass something by reference, in which case they would not get the behaviour they desire.在其他情况下,人们可以在实际想要通过引用传递某些内容时使用结构,在这种情况下,他们将无法获得他们想要的行为。

Just as an example for better understanding仅作为更好理解的示例

// obviously creates a new Stats instance
player.Stats = new Stats();

// only changes the value inside the instance - no copy
player.Stats.Speed = 3;

// A new copy
var states = player.Stats;

// Creates and passes a COPY to the method 
JsonUtility.ToJson(player.Stats)

// again no copy
player.Stats.SetSpeed(3);

And just for providing one example for a well known struct type ;)只是为了提供一个众所周知的struct类型的例子;)

// stores a COPY 
var position = transform.position;

// only changes a value - no copy
position.x = 4;

// normalizes the instance itself - no copy
position.Normalize();

// Assigns a COPY
transform.position = position;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM