Skal det være i dag?

by Jesper april 22, 2009 23:04

Under mit spike (Scrumm’s term for research) på et event DSL, løb jeg ind i et behov for at angive et ugedagsfilter. Altså en måde at angive dage i en ugentlig gentagelse. Det skal være muligt at filtrere f.eks. mandage, tirsdage og fredage. Mit første take på opgaven var at bruge en ‘bitmaske’ – altsås: søndag: 0x01, mandag: 0x02, , , lørdag: 0x40. Man vil så kunne bestemme om en given dato overholder filtret ved at lave en logisk ‘og’:

public class DayOfWeekFilter1
{
    public DayOfWeekFilter1(bool su, bool mo, bool tu, bool we, bool th, bool fr, bool sa)
    {
        if (su) filter |= 0x01;
        if (mo) filter |= 0x02;
        if (tu) filter |= 0x04;
        if (we) filter |= 0x08;
        if (th) filter |= 0x10;
        if (fr) filter |= 0x20;
        if (sa) filter |= 0x40;
    }

    int filter;

    public bool IsMatch(DateTime input)
    {
        int d = (int)input.DayOfWeek + 1;
        return (d & filter) == d;
    }
}

Jeg synes løsningen er simpel og logisk, men en bekendt påpegede over for mig, at koden var svær at gennemskue, og at hun til hver en tid ville foretrække et filter af følgende form:

public class DayOfWeekFilter2
{
    public DayOfWeekFilter2(bool su, bool mo, bool tu, bool we, bool th, bool fr, bool sa)
    {
        this.mo = mo;
        this.tu = tu;
        this.we = we;
        this.th = th;
        this.fr = fr;
        this.sa = sa;
        this.su = su;
    }
    bool mo, tu, we, th, fr, sa, su;

    public bool IsMatch(DateTime input)
    {
        if (su && input.DayOfWeek == DayOfWeek.Sunday)
            return true;
        if (mo && input.DayOfWeek == DayOfWeek.Monday)
            return true;
        if (tu && input.DayOfWeek == DayOfWeek.Tuesday)
            return true;
        if (we && input.DayOfWeek == DayOfWeek.Wednesday)
            return true;
        if (th && input.DayOfWeek == DayOfWeek.Thursday)
            return true;
        if (fr && input.DayOfWeek == DayOfWeek.Friday)
            return true;
        if (sa && input.DayOfWeek == DayOfWeek.Saturday)
            return true;
        return false;
    }
}

Jeg har selvfølgelig svært ved at argumenterer mod at koden er kompleks (det kommer jo an på øjnene der ser), men jeg vil gerne kunne sige at ‘min’ måde er mere effektiv (hurtigere), da den er mere simpel (IL-koden fylder 1/5).

Jeg satte en lille test op, hvor jeg testede 1 million datoer. Forskellen var meget begrænset under 100 ms med et filter der tog mandage. Hvis filtret tog alle dage undtagen mandage, var forskellen ca 600 ms. Det skyldes selvfølgelig at filtret får en ekstra kondition at checke for hver dag der tilføjes filtret.

Effektiviteten er ikke signifikant bedre, så man kan vel sige at Signes argument om uigennemskuelig kode er valid…men jeg holder mig nu til min første indskydelse :-)

Code on…

Tags:

Kommentarer

23-04-2009 07:22:55 #

Brian

Hvorfor bruger du ikke en enum, så er du fri for den ikke særlig smukke syv-bools-til-bits-metode? Der er masser af eksempler på lignende features i frameworket, så udviklere burde kende metoden.

Brian Denmark

23-04-2009 08:03:38 #

Jesper

@Brian> God pointe. Man skal bare huske at bruge Flags-attributten på den enum.


var filter = new DayOfWeekFilter(Weeekdays.Mo | Weekdays.We | Weekdays.Weekend)

Jesper Denmark

Kommentarerne er lukkede

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen | Modified by Mooglegiant

About

Mit navn er Jesper Jensen, og jeg arbejder til dagligt som web-udvikler hos DGI, hvor mit speciale er klientside applikationer. Før det var jeg nogle år i robotbranchen, hvor jeg arbejdede med 3D simulering og system koordinering. Jeg elsker webudvikling, og specielt JavaScript har min interesse. Jeg har blogget om mine oplevelser med udvikling siden 2004

Calendar

<<  september 2010  >>
mationtofr
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

View posts in large calendar

RecentComments

Comment RSS