假设指定的日期有效且属于公历,我们假设爱丽丝和鲍勃被分配了一个函数,为格里高利历的给定日期返回星期几。
是否有广泛接受的指南(或最佳做法),允许告诉哪些代码更好,为什么?
爱丽丝:
int getDayOfWeek(int day, int month, int year)
{
int monthBias[] = { 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5 };
int yearsBefore = year - 1;
unsigned int result = yearsBefore + yearsBefore / 4 - yearsBefore / 100 + yearsBefore / 400 + monthBias[month - 1] + day;
if (year % 4 == 0 && month > 2 && (year % 100 != 0 || year % 400 == 0))
++result;
return result % 7;
}
鲍勃:
enum DayOfWeek
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
count
};
inline int getLeapYearsBefore(int year)
{
int yearsBefore = year - 1;
return yearsBefore / 4 - yearsBefore / 100 + yearsBefore / 400;
}
inline bool isLeapYear(int year)
{
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}
using namespace std;
template <typename T, size_t n>
constexpr size_t arraySize(T (&)[n]) { return n; }
DayOfWeek getDayOfWeek(int day, int month, int year)
{
const int
commonYear[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
leapYear[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
daysInCommonYear = accumulate(commonYear, commonYear + arraySize(commonYear), 0),
daysInLeapYear = accumulate(leapYear, leapYear + arraySize(leapYear), 0),
yearsBefore = year - 1,
leapYearsBefore = getLeapYearsBefore(year),
commonYearsBefore = yearsBefore - leapYearsBefore;
auto kindOfYear = isLeapYear(year) ? leapYear : commonYear;
unsigned int result =
(leapYearsBefore * daysInLeapYear
+ commonYearsBefore * daysInCommonYear
+ accumulate(kindOfYear, kindOfYear + month - 1, day)) % DayOfWeek::count;
return static_cast<DayOfWeek>(result);
}
性能比较并没有为Alice的代码带来可检测的优势,因为我试图测量Alice和Bob的实现的性能差异,但是失败了(使用high_resolution_clock::now()
和duration_cast<nanoseconds>(end - start)
) - 至少我可以说差异小于0.5%(在500万次通话中平均通话时间之间)。
答案 0 :(得分:2)
如果您正在寻找指导方针,我建议您阅读Stroustrup的C ++编程语言书。
但简单地说,这是两种不同的方法:
Alice方法(为什么要使用它): 用于需要高性能的程序的简单方法 - 一个功能(一个电话) - 仅在需要时声明变量 - 使用已知大小的静态分配向量 - 没有详尽使用对象副本。
Bob方法(为什么应该使用它):
它基于分而治之的策略。 - 每个函数负责一个任务(如果您希望将来维护代码,则非常有用) - 用于其他目的的高度可重用代码。
答案 1 :(得分:1)
与生活中一样,没有比较两种方法的简单方法,不同的人可能对他们有不同的看法。如果要将这些功能合并到生产代码中,那么有两件事情会计算在内:
所以&#34;清除&#34;答案是:取决于。
假设鲍勃的代码只是稍微慢了一点,而且这个功能并不是那么重要,那么我会投票选择鲍勃的方法 - 做完一些时间后。
答案 2 :(得分:-1)
它们与@ tobi303说的不同,但我看到第一个实现的计算量较少,第二个更容易理解。
如果它们相似,你可以按照提到的测试用例和性能测量(即执行时间)进行比较。
修改:&#34;我看到&#34;第二个是可以理解的,因为有意义的标识符。
year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)
如果我没有读取函数名,我不知道得到真实结果意味着什么。