在 set 方法中赋值前检查当前值
Check current value before assignment in set method
我将从我在 Internet 上找到的应用程序的代码片段开始。它是用 C++ 制作的,但该主题可以针对任何编程语言:
class AppSettings
{
public:
AppSettings() {m_value = 0;}
~AppSettings();
void AppSettings::setValue(uint value)
{
if (m_value != value)
m_value = value;
}
private:
uint m_value;
};
您真的需要在赋值前检查当前值与新值是否不同吗?
仅仅是编程风格、效率、礼貌还是什么?
一般来说,在class的set方法中,是否需要检查新值是否与当前值不同?
Do you really need to check that the current value differs from the new one before assignment? Is it just a programming style, efficiency, good manner, or what?
我觉得像 cruft。
当您在编写代码时混合两种想法("We only update state when necessary" 与 "the setter just sets the value")时,您通常会得到这样的代码,并且示例代码最终没有清楚地表达任何一种想法。
虽然我不能说 - 我必须阅读你从中获取代码的文章。
General speaking, in set method of a class, do you need to check that new value differs from current one?
你做,当你优化,或者当你需要用代码表达的想法是"perform updates when necessary"。
考虑这个(人为的和设计的)代码:
/// object in 2D space
class TwoDObject
{
/// shift object position
void shift_position(int x, int y)
{
if(x != x_ || y != y_)
{
x_ = x;
y_ = y;
render_shadows();
}
}
private:
// render the shadows cast by this object (slow implementation)
void render_shadows();
int x_;
int y_;
};
在这种情况下,你有一个内部状态更新,然后是副作用(当你改变位置时阴影已经改变)。
因为渲染阴影的方法很慢,所以只在需要的时候调用它。
这在很大程度上取决于被分配成员的类型。如果它是原始类型或同样轻量级的东西,则检查很可能是悲观的:分配可能比条件跳转便宜得多。请记住,基本上所有现代处理器都是基于流水线的,如果分支预测失败,条件跳转会导致需要中止流水线。这会降低效率。
如果类型的分配成本更高,答案就不那么明确了。例如,复制大量数据缓冲区是一项代价高昂的操作。但是,比较它的相等性也是如此。要决定是盲目分配还是先比较,您需要了解所讨论类型的特性,并评估相同的频率-可能会发生值分配,识别它们的速度有多快,以及与复制相比这种识别的成本有多高 "blindly." 另外请记住,如果比较表明它们的值不同,那么您将为两者付出代价:比较,然后复制。
最后,有些情况需要检查:当赋值有副作用时。例如,如果成员的类型使其在分配给时发出通知,您很可能需要进行比较以避免虚假通知(当然,假设您不想要这些通知)。
总而言之,没有硬性规定,但我想说的是,平均而言,只有在有充分理由的情况下才应该包括比较。
这实际上取决于您要设置的内容,我的意思是,如果您设置的内容会传播更改,那么执行此操作很重要。如果在这种情况下更改的成本相当大(重新排序整个数组、更新某个网络位置的数据、重写一个大文件),并且如果程序需要实时性能,那么检查不必要的更改是一个很好的做法。如果更改没有副作用,最好只是更改它并避免额外的分支。
我将从我在 Internet 上找到的应用程序的代码片段开始。它是用 C++ 制作的,但该主题可以针对任何编程语言:
class AppSettings
{
public:
AppSettings() {m_value = 0;}
~AppSettings();
void AppSettings::setValue(uint value)
{
if (m_value != value)
m_value = value;
}
private:
uint m_value;
};
您真的需要在赋值前检查当前值与新值是否不同吗? 仅仅是编程风格、效率、礼貌还是什么?
一般来说,在class的set方法中,是否需要检查新值是否与当前值不同?
Do you really need to check that the current value differs from the new one before assignment? Is it just a programming style, efficiency, good manner, or what?
我觉得像 cruft。
当您在编写代码时混合两种想法("We only update state when necessary" 与 "the setter just sets the value")时,您通常会得到这样的代码,并且示例代码最终没有清楚地表达任何一种想法。
虽然我不能说 - 我必须阅读你从中获取代码的文章。
General speaking, in set method of a class, do you need to check that new value differs from current one?
你做,当你优化,或者当你需要用代码表达的想法是"perform updates when necessary"。
考虑这个(人为的和设计的)代码:
/// object in 2D space
class TwoDObject
{
/// shift object position
void shift_position(int x, int y)
{
if(x != x_ || y != y_)
{
x_ = x;
y_ = y;
render_shadows();
}
}
private:
// render the shadows cast by this object (slow implementation)
void render_shadows();
int x_;
int y_;
};
在这种情况下,你有一个内部状态更新,然后是副作用(当你改变位置时阴影已经改变)。
因为渲染阴影的方法很慢,所以只在需要的时候调用它。
这在很大程度上取决于被分配成员的类型。如果它是原始类型或同样轻量级的东西,则检查很可能是悲观的:分配可能比条件跳转便宜得多。请记住,基本上所有现代处理器都是基于流水线的,如果分支预测失败,条件跳转会导致需要中止流水线。这会降低效率。
如果类型的分配成本更高,答案就不那么明确了。例如,复制大量数据缓冲区是一项代价高昂的操作。但是,比较它的相等性也是如此。要决定是盲目分配还是先比较,您需要了解所讨论类型的特性,并评估相同的频率-可能会发生值分配,识别它们的速度有多快,以及与复制相比这种识别的成本有多高 "blindly." 另外请记住,如果比较表明它们的值不同,那么您将为两者付出代价:比较,然后复制。
最后,有些情况需要检查:当赋值有副作用时。例如,如果成员的类型使其在分配给时发出通知,您很可能需要进行比较以避免虚假通知(当然,假设您不想要这些通知)。
总而言之,没有硬性规定,但我想说的是,平均而言,只有在有充分理由的情况下才应该包括比较。
这实际上取决于您要设置的内容,我的意思是,如果您设置的内容会传播更改,那么执行此操作很重要。如果在这种情况下更改的成本相当大(重新排序整个数组、更新某个网络位置的数据、重写一个大文件),并且如果程序需要实时性能,那么检查不必要的更改是一个很好的做法。如果更改没有副作用,最好只是更改它并避免额外的分支。