3

我的一位同事正在编写一份报告,该报告显示了我们小型咨询公司中每位员工每周(周日至周六)的进展情况。他编写的一段代码显示了与目标周中的日期相对应的列。他的算法如下:

  1. 获取该月的第一天是一周中的哪一天。如果是星期天,将标志设置为零;否则,将其设置为 1。
  2. 遍历一个月的所有日子。如果是星期天,增加标志。然后,如果标志的值等于要显示的星期,则显示对应于当天的列;否则,隐藏该列。

当然,标志表示当前周是什么。

我建议了另一种算法:

  1. 获取该月的哪几天是指定周的第一天 (F) 和最后 (L) 天。例如,2009 年 10 月的第一周从周二 1 日开始,到周六 3 日结束。
  2. 遍历对应于第 1 天到 F-1 天的列,并隐藏它们。
  3. 遍历对应于天 F 到 L 的列,并显示它们。
  4. 遍历对应天 L+1 到 DaysOfMonth 的列,并隐藏它们。

我的算法中的“困难”部分是第 1 部分。我的意思是“难以理解”中的“困难”,因为这样做的算法复杂性是恒定的。而且我的算法的优点是循环更紧密。我的同伴的循环对每个月的每一天进行比较。我的没有。

这是一个小例子,你可能会说这里的过度优化有点太偏执了。但是当我们编写实际的性能关键代码时,他的编程风格并没有改变。

他的代码也充满了这些测试:

/* doSomething() doesn't change the state of the relevant variables. */
if (condition)
{
    flag++;
    if (flag > test)
        doSomething();
}
else
    if (flag >= test)
        doSomething();

当然,什么时候可以这样做:

if (flag >= test);
    doSomething();
if (condition)
    flag++;

我该怎么办?!?!?!

编辑:我更正了代码示例中的比较。

4

8 回答 8

10

我觉得你朋友的想法是对的。采用明显正确的算法,而不是需要一个小时才能解释的算法,但在没有特别的性能目标的情况下,它更快。

如果您有特定的性能要求,例如“代码需要能够在机器 X 上的 200 微秒内为未来十年的所有月份提供正确的结果”,更简单的代码无法满足要求,那么您可以考虑使用您的版本。

(您发布的代码示例确实以您的方式更好,因为它不那么复杂。)

于 2009-10-31T13:58:56.420 回答
5

根据您的描述,我不确定我是否不同意您的同事。这里的关键问题是这段代码是否是性能瓶颈

为了说服切换到您的算法,您必须分析有问题的应用程序并向我展示这段代码对性能至关重要。然后进行更改并再次对其进行配置。这样你就有了比较的客观依据

如果两种算法之间存在有意义的差异,那么你们两个可以讨论是否值得进行转换。

如果您担心 Web 应用程序的页面加载时间,请记住高性能网站Yahoo 性能指南的课程- 您如何处理 CSS、javascript 和缓存将比优化运行在您的应用程序上的算法产生更大的影响。服务器。

提倡没有测量的优化与忽略朴素算法的性能影响一样危险。

于 2009-10-31T13:59:09.177 回答
4

好吧,您不应该干涉,因为显然您错了……两段代码不等价。只需条件=1,标志=0和测试=1

于 2009-10-31T14:05:36.470 回答
3

这是你的任务,还是他的任务?如果是他的,就让他去做。我是一个追求效率的人,事实上,当某些事情看起来效率低下并且超出我的控制范围时,我会变得非常沮丧。

SO上有超过200人可以让我最“有效”的想法、算法和代码感到羞耻。可能更多,你不能单独通过代表。如果 Linus Torvalds 自己报名参加,他会像我们其他人一样从 1 开始。

您必须考虑的是人们需要能够维护他们编写的代码。这意味着,他们必须理解它,就好像他们生了它一样。即使有人演示了另一种算法比我自己的算法更有效,除非我对它感到满意,否则我不会使用它。

如果这是一个联合项目,请按照自己的方式编写,展示速度,然后花一些非常非常耐心的时间与您的同伴一起帮助他真正掌握它。

回顾你 5 年前写的东西,每个人都必须边做边学,每个人都按照自己的速度做事,尤其是学习。

于 2009-10-31T14:02:10.050 回答
3

天,

我建议您应该支持在您的约束范围内执行的算法简单性,而不是提供没有真正收益的​​聪明、过于复杂的算法。根据我的经验,这些过于聪明的技巧很可能会成为未来维护的噩梦!

这个想法可以通过以下引用更好地表达:

“称职的程序员完全意识到自己头骨的大小受到严格限制;因此他以完全谦逊的态度处理编程任务,除此之外,他还避免了像瘟疫这样的巧妙技巧。” - Edsger Dijkstra 在他的 1972 ACM 图灵讲座“谦逊的程序员”中

顺便说一句,那篇论文读起来很棒!以及他在EWDijkstra 档案馆在线提供的许多其他论文

高温高压

干杯,

于 2009-10-31T14:13:17.633 回答
2

我没有看到这里的问题......虽然他的版本有一点迂回的方式来达到目标​​,但他确实到达了那里。

我要说的这句话不应该断章取义:但总会有人那样做——这并没有错,恰恰相反……他可能不知道一个好的方法做某事,但他确实知道如何得到结果,无论他的方法多么丑陋。
当没有人知道某事的正确算法时,这可能是一个真正的救命稻草……他很可能会以某种方式将其录音

于 2009-10-31T14:10:51.460 回答
2

我同意这里普遍存在的观点:如果性能改进会使代码更难阅读,那么最好有充分的理由进行这种更改。

另一方面,这并不意味着我们应该总是满足于首先想到的事情。有时,有明确的更好的替代方案,它们同样可读或几乎可读。

如果你想说服你的同事认真对待他选择的算法,你应该谨慎选择你的战斗。不要试图把他的世界颠倒过来,把问题强加在你发现的每一个案例上。仅当您可以想到一种明显优越且清晰的替代算法时,才开始提出建议,并准备好在他拒绝时退缩。

如果你觉得自己很狡猾,你甚至可以给他一些提示,问一些引导性的问题,或者任何你能想到的其他技巧来帮助他自己解决问题。

于 2009-10-31T14:28:59.230 回答
1

我感觉到你的痛苦。程序员的本性真的很顽固。每个人都有自己构建程序的原则和规则。如果其他意见与当时的某些意见发生冲突,改变程序员的意见就像移动摩天大楼的基础支柱。:)

于 2009-10-31T17:25:21.027 回答