亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 C# (Unity) 中使用靜態臨時變量有什么好處嗎?

在 C# (Unity) 中使用靜態臨時變量有什么好處嗎?

C#
一只名叫tom的貓 2023-08-20 14:38:18
我想在我的下一個項目中使用更好的實踐,其中可讀性顯然很有價值,但性能更重要。所以考慮這兩段代碼......在靜態溫度...public class Shot : MonoBehaviour {? ? static Actor tempActor;? ? static Vector3 tempVec;? ? static float tempFloat;? ? static HitResult hitResult;? ? public float damage;? ? public float unblockable;? ? public Vector3 originationPoint;? ? private void OnTriggerEnter(Collider collision) {? ? ? ? if (collision.gameObject.layer == 11) {? ? ? ? ? ? tempActor = collision.gameObject.GetComponent<Actor>();? ? ? ? ? ? if (tempActor != null) {? ? ? ? ? ? ? ? tempVec = collision.transform.position - originationPoint;? ? ? ? ? ? ? ? // cast ray? ? ? ? ? ? ? ? originatorActor.RayDisableColliders();? ? ? ? ? ? ? ? bool rayHit = Physics.Raycast(originationPoint, tempVec, out hitResult, range, 1<<11, QueryTriggerInteraction.Ignore);? ? ? ? ? ? ? ? if (rayHit) {? ? ? ? ? ? ? ? ? ? if (hitResult.collider.gameObject.CompareTag("Hero") || hitResult.collider.gameObject.CompareTag("Villain")) {? ? ? ? ? ? ? ? ? ? ? ? tempActor = hitResult.collider.gameObject.GetComponent<Actor>();? ? ? ? ? ? ? ? ? ? ? ? tempActor.HitByShot(class_utilities.GetAngle(hitResult.transform, originationPoint), damage, unblockable);? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? originatorActor.RayEnableColliders();? ? ? ? ? ? }? ? ? ? }? ? }}當地宣布的臨時工public class Shot : MonoBehaviour {? ? public float damage;? ? public float unblockable;? ? public Vector3 originationPoint;? ? private void OnTriggerEnter(Collider collision) {? ? ? ? if (collision.gameObject.layer == 11) {? ? ? ? ? ? Actor tempActor = collision.gameObject.GetComponent<Actor>();? ? ? ? ? ? if (tempActor != null) {? ? ? ? ? ? ? ? Vector3 offset = collision.transform.position - originationPoint;? ? ? ? ? ? ? ? // cast ray? ? ? ? ? ? ? ? originatorActor.RayDisableColliders();? ? ? ? ? ? ? ? HitResult hitResult;兩種方法之間在性能方面有什么區別,特別是在我看來內存分配和垃圾收集?
查看完整描述

2 回答

?
喵喵時光機

TA貢獻1846條經驗 獲得超7個贊

最大的問題不是性能 - 而是正確性。以這種方式使用靜態字段會改變含義,并可能導致以下任一方面的大問題:

  • 多個線程訪問相同的靜態值并在進程中互相踩踏

    • 作為一種特殊情況,這不僅可能導致意外的值,而且還可能導致“撕裂”值,因為您提到了過大的結構,例如Vector3

  • 任何需要重入的東西;調用堆棧中的每個方法都會忽略該值,而不考慮任何預期的行為

基本上:除非你有很好的理由,否則不要這樣做(即不要濫用臨時本地變量的靜態字段);請改用常規局部變量。


性能上有什么區別嗎

就速度而言,幾乎肯定不是,但你必須使用 benchmarkdotnet 之類的東西來衡量它

在我看來,尤其是內存分配和垃圾收集

通過將值放入靜態字段,您可以通過該值使任何對象可達:可達。如果您從不清除該字段,它可能會不必要地使任意大的對象圖保持活動狀態。


查看完整回答
反對 回復 2023-08-20
?
Smart貓小萌

TA貢獻1911條經驗 獲得超7個贊

我傾向于同意 Marc Gravell 的主要概念,但我認為他的答案更多地與 C# 相關,而不是與 Unity 相關。

是的。我同意 C# 明智地將靜態值與線程混合可能會產生問題......

但在您的特定情況下,OnTriggerEnter可以僅在主線程上運行(例如許多其他與統一相關的方法),因此您沒有這樣的風險(除非您開始在方法之外使用這些字段OnTriggerEnter)。

無論如何,情況是這樣的:

速度性能

參考文獻類型

  • 無論如何,參考值都會存在于堆中。從速度方面來說,最好將它們保持靜態,否則它們將繼續從堆中分配/取消分配。

價值類型

  • 對于值類型則是另一回事了。如果它們是靜態的,您將把它們永久存儲在堆上(幾乎在所有情況下),而本地值類型將存在于堆棧中(壽命相當短......)

  • 如果您將它們作為靜態放在堆上,我預計,一般來說,您將需要更多時間來訪問它們

  • 如果將它們分配在堆棧中(作為本地值),速度會快得多

內存性能

  • 對于值類型,最好將它們分配在堆棧中(以及本地值)。

  • 內存方面,引用類型也應該比本地值更好。您可以根據需要將它們保留在內存中。正如馬克所解釋的,使用靜態字段,您可以將它們無限期地保留在內存中。

值類型肯定比本地值更好。引用類型在速度方面比靜態的性能更高,但在內存方面比本地的性能更高。

一般來說,在您的具體情況下,即使是大量呼叫,我也沒有看到任何大的變化。

您仍然可以嘗試使用Unity 基準測試工具對其進行基準測試(因為BenchmarkDotNet不適用于開箱即用的 Unity)。

就我而言...

我會使用本地值,更具可讀性。


查看完整回答
反對 回復 2023-08-20
  • 2 回答
  • 0 關注
  • 154 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號