嘿伙计们,所以我做了这个功能,每个帧调用。 - 您认为这是保存性能的好方法还是有更好的方法?
private void GetCurrentTime()
{
m_TimeNow = System.Convert.ToString(System.DateTime.Now);
//If the previous time is not equals to the current time (without seconds = every minute)
if (m_PreTime != m_TimeNow.Remove(14))
{ //Change the Time displayed on the screen:
m_PreTime = m_TimeNow.Remove(14); //1. Copy current Time
m_Times = m_TimeNow.Split(' '); //2. Split to following parts
m_Time = m_Times[1].Remove(4); //3. Cutout seconds
m_Text_Time.text = m_Time + " " + m_Times[2]; //4. And change UI-Text: Time + AM/PM
}
}
此功能在每个帧中调用,并且将在移动设备上运行。
谢谢!
答案 0 :(得分:0)
我可能会看到您的实施方面有所改进。以下是我根据自己的经验告诉你的事情。
//
// Version 2
//
class TimerExample_V2 {
private DateTime _TimeNow = System.DateTime.Now;
private DateTime _PreTime = System.DateTime.Now;
private string _format = "t";
private string _cultureName = "en-US";
public TimerExample_V2() {
CultureInfo culture = new CultureInfo(_cultureName);
CultureInfo.CurrentCulture = culture;
}
public void UpdateCurrentTimeUI() {
_TimeNow = System.DateTime.Now;
if(_PreTime.Minute != _TimeNow.Minute) {
// Note: this case appear only once per minute.
_PreTime = System.DateTime.Now;
string newText = _TimeNow.ToString(_format);
//m_Text_Time.text = newText; // Update unity display
// I omit this display unity. (Same cost in both case)
}
}
字符串(性能): 字符串通常很昂贵,特别是在处理str处理和比较时。例如,'String.Remove(int)'创建一个新字符串,可以调用几个昂贵的方法,如malloc等(在场景后面)。据我所知,您将所有日期保留为字符串,但只能使用原始格式DateTime。更好的方法是将数据保持为“DateTime”格式,并将其转换为仅供最终用户使用的字符串。 (例如,更新Unity显示)。最好比较两个int(例如:DateTime.ElapsedMilliseconds)而不是字符串(例如:m_PreTime!= m_TimeNow.Remove(14))
日期格式(灵活性): 在处理不同的日期格式时,您会遇到几个问题。您的实现需要“HH:mm AM / PM”格式,但用户可能有可能更改格式(例如24小时)。使用C#为您提供的暗魔力。例如,使用CultureInfo或已经实现的“DateTime.ToString(format)”。 (我刚刚了解了'CultureInfo'。可能还有其他方法。但作为一般规则,看看语言是否已经具备了你需要的功能。
功能名称: 这是一个小东西,但尝试使用它所说的功能。在您的情况下,从'GetCurrentTime',我们期望返回值。此函数实际更新显示并返回void。像'UpdateTimeDisplay'这样的东西可能更好。
重复通话: 第二件小事:你有2次调用m_timeNow.Remove(14)。您可以创建一个新字符串(从此函数)并在两个位置使用此新字符串。
无论如何,在处理性能时,您必须测量,对代码进行基准测试。 (作为一个例子,我首先为你的GetCurrentTime做了一个实现,并意识到它实际上并没有更好。)以下是我创建的一些经验,以向您展示一些测量。我不是C#萨满专家,也不是性能向导专家,但我希望我的例子很清楚。我在笔记本电脑上运行实验:( Intel i5-3320M CPU @ 2.60GHz)。
我有两个函数实现。我运行每个函数10 000次并打印每个函数的执行时间。 (我省略了更新统一显示的调用,两种情况都是一样的)。我的测量显示你的实现花费了45毫秒,另一个花了23毫秒。
第二种实现听起来更好。但是,不要忘记我拨打了10 000次这些功能。在实践中,使用60fps,您每秒呼叫更新60次。在我的笔记本电脑上,60次迭代花费了0毫秒。
还有另一个要点:
m_PreTime = m_TimeNow.Remove(14);
m_Times = m_TimeNow.Split(' ');
m_Time = m_Times[1].Remove(4);
自从处理字符串创建以来,这些函数很慢。但是,每分钟只调用一次。作为一个fack,我测量了一下,我的实现,当切换分钟时,使用与你的相同的毫秒数。我可能没有通过我的测量或其他什么,但也许,每一分钟,我的功能需要花费你的时间。在所有其他情况下,它“更快”。我可以用引号来总结这一点:
“首先解决最常见的情况,不是最通用的”
(据我记得,这是关于优化的讨论:https://www.youtube.com/watch?v=nXaxk27zwlk。好的谈话顺便说一下)
所以这是我可怕的实验的完整代码:
using System;
using System.Globalization;
using System.Diagnostics;
// Instructions to compile (With mono)
// csc Program.cs
// mono Program.exe
class Program {
static void Main(string[] args) {
TimerExample_V1 timer_v1 = new TimerExample_V1();
TimerExample_V2 timer_v2 = new TimerExample_V2();
Stopwatch profiler;
int nbBenchLoops = 10000; // 10 000 times
float t1;
float t2;
// Profil version 1
profiler = Stopwatch.StartNew();
for(int k = 0; k < nbBenchLoops; ++k) {
timer_v1.UpdateCurrentTimeUI();
}
t1 = profiler.ElapsedMilliseconds;
// Profil version 2
profiler = Stopwatch.StartNew();
for(int k = 0; k < nbBenchLoops; ++k) {
timer_v2.UpdateCurrentTimeUI();
}
t2 = profiler.ElapsedMilliseconds;
// Print mesured times
Console.WriteLine("[SCOPE_PROFILER] [Version 1]: {0} ms", t1);
Console.WriteLine("[SCOPE_PROFILER] [Version 2]: {0} ms", t2);
}
}
//
// Version 1
//
class TimerExample_V1 {
private string m_TimeNow = System.Convert.ToString(System.DateTime.Now);
private string m_PreTime = System.Convert.ToString(System.DateTime.Now);
private string[] m_Times;
private string m_Time;
public void UpdateCurrentTimeUI() {
m_TimeNow = System.Convert.ToString(System.DateTime.Now);
if (m_PreTime != m_TimeNow.Remove(14)) {
// Note: this case appear only once per minute.
m_PreTime = m_TimeNow.Remove(14);
m_Times = m_TimeNow.Split(' ');
m_Time = m_Times[1].Remove(4);
string newText = m_Time + " " + m_Times[2];
//m_Text_Time.text = newText; // Update unity display
// I omit this display unity. (Same cost in both case)
}
}
}
//
// Version 2
//
class TimerExample_V2 {
private DateTime _TimeNow = System.DateTime.Now;
private DateTime _PreTime = System.DateTime.Now;
private string _format = "t";
private string _cultureName = "en-US";
public TimerExample_V2() {
CultureInfo culture = new CultureInfo(_cultureName);
CultureInfo.CurrentCulture = culture;
}
public void UpdateCurrentTimeUI() {
_TimeNow = System.DateTime.Now;
if(_PreTime.Minute != _TimeNow.Minute) {
// Note: this case appear only once per minute.
_PreTime = System.DateTime.Now;
string newText = _TimeNow.ToString(_format);
//m_Text_Time.text = newText; // Update unity display
// I omit this display unity. (Same cost in both case)
}
}
}
有关DateTime.ToString和CultureInfo的更多信息,请查看文档:
希望这会有所帮助:)