优化Groovy代码

时间:2015-04-07 20:37:56

标签: groovy

我是Groovy / Grails竞技场的新手。我最近修改了一些代码来添加以下块。

result.processed.each{
    def queueEntry = QueueEntry.findById(it.id)<<<START ADD>>>
    Set dates = new HashSet<Long>()

    def children = QueueEntry.findAllByParent(queueEntry)

    for(QueueEntry qe : children){
        def f = new GregorianCalendar()
        f.setTimeInMillis(DateUtils.getClearedTime(qe.entryTimestamp))
        def l = new GregorianCalendar()
        l.setTimeInMillis(DateUtils.getClearedTime(qe.exitTimestamp))
        while(f < l){
            if(f.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY && f.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY){//only add weekdays
                dates.add(f.time.time)
            }
            def xx = new GregorianCalendar()
            xx.setTimeInMillis(f.time.next().time)
            f = xx
        }
        dates.add(l.time.time)
    } <<<STOP ADD>>>
    Set outsideDays = it.numberOfDaysOutsideCVB
    Set days = DateUtils.businessDaysBetweenDates(it.entryTimestamp, it.exitTimestamp)
    days.removeAll(outsideDays)
    days.removeAll(dates)
    turnTimes << days.size()
}

该应用程序现在正在抓取。我显然做错了什么。当针对小型数据集运行时,它将缓慢完成。在较大的套装上它没有完成。在此更改之前,它正在完成。

1 个答案:

答案 0 :(得分:0)

您可以从以下更改的行开始。

// Proposed

import static java.util.Calendar.*

// Query for all the children upfront instead of hitting
// database twice on each iteration. 
// You can also avoid N + 1 situation if children is fetched eagerly
def allChildren = QueueEntry.where {
    id in (result.processed*.id as List<Long>)
}.children.list() 

def turnTimes = result.processed.collect { entry ->
    allChildren.findAll { it.parent.id == entry.id }.collect { child ->
        Set dates = []
        new Date( child.entryTimeStamp ).upto( new Date( child.exitTimestamp ) ) {
            if ( !( it[DAY_OF_WEEK] in [ SUNDAY, SATURDAY ] ) ) {
                dates << it.time
            }
        }
        Set outsideDays = child.numberOfDaysOutsideCVB
        Set days = 
            DateUtils.businessDaysBetweenDates(
                child.entryTimestamp, 
                child.exitTimestamp 
            )

        ( days - outsideDays - dates )?.size() ?: 0
    }
}

<强>假设:

  • QueueEntry hasMany children
  • entryTimestamp / exitTimestampjava.sql.Timestamp
  • entryTimestamp / exitTimestamp不为空且entryTimestamp位于exitTimestamp之前。

正如伯特所说,这个问题最适合codereview.stackexchange.com