在以下代码段中(硬编码值只是一个示例):
int nBulk = 30, // bulk size
nMax = 130; // max records to retrieve
nRetrieved = 0; // records retrieved so far
do
{
var response = GetRecords(nBulk);
nRetrieved += response.Count;
nBulk = nMax - nRetrieved >= nBulk ? nBulk : nMax - nRetrieved;
}
while (nRetrieved < response.Total && nRetrieved < nMax);
使用三元表达式为 nBulk
分配了一个新值。
三元表达式可以用简单的算术表达式替换(即没有分支)吗?
答案 0 :(得分:0)
没有任何内容表明nMax==response.Total
:因此我推断上一个GetRecords
请求将返回有效nRetrieved <= nRequested
。
如果GetRecords
具有足够的可读容量,则无需从您显示的代码中修改循环内的nBulk
。
但是,如果我看到这样的代码,我的推论是修改nBulk
的最后一次读取可能是必要的,因为GetRecords
有副作用 - 比如填充缓冲区 - IOW,a保护是绝对必要的,以避免缓冲区溢出。
在这种情况下,分支是最少的问题:使用方法/函数修改状态,但需要知道发送者/呼叫者站点的内部缓冲区限制(nMax
)是危险的! / p>
这就是为什么我倾向于移动保护技术。 nMax
方法/函数中的GetRecords
而不是外部,如果这样做,问题在发送站点得到解决:不再需要在循环中修改nBulk
,也不需要设计约nMax
。
当然,测试将在GetRecords
内移动,因此不会消失。但坦率地说,为什么会出现问题呢?你不能增加bulkSize,这样这个测试就变得完全可以忽略了吗?
如果由于某种原因你不能,那么:
循环中还有一个测试(nRemaining&gt; = nBulk),所以这一切似乎都没用。
要避免此测试,您必须确保当有足够的内容时,有效nRetrieved
等于请求的nBulk
(代码中没有任何内容表示)。
在这种情况下,您可以在步骤3执行除法。nLoop=integer_floor_division(Total/nBulk)
,执行此循环次数(并让一些编译器为您执行循环展开,以便平均减少测试次数) ,然后在步骤4为剩余的(模数/余数)Total%nBulk
执行GetRecords。
所有你会得到的IMO是一个更脆弱和脆弱的代码,有可能通过填充代码缓存来消除边际收益......你应该问的问题是:我真的需要这种微优化吗?为什么?
答案 1 :(得分:0)
答案是是,但这很难看:
nBulk = (nBulk + (nMax - nRetrieved) + Math.Abs(nBulk - (nMax - nRetrieved)))/2;
如果你想避免Abs
,那么你可以这样做:
nBulk = (nBulk + (nMax - nRetrieved)
+ Math.Sqrt((nBulk - (nMax - nRetrieved)) * (nBulk - (nMax - nRetrieved))))/2;
这可能更糟。
长话短说,没有好的&#34;语言不可知&#34;这样做的方法是因为没有Lanugae Agnostic方法可以从布尔转换为没有分支的整数。在那些您只是说:
的语言中int i = (true);
然后,这是一个不同的故事。