Асинхронная работа файлов FileTree? - PullRequest
2 голосов
/ 01 сентября 2011

Есть ли способ, с помощью которого я могу легко сделать обработку файлов FileTree умным способом в задачах Gradle?Мне в основном нужно дождаться выполнения всех файлов, очень похоже на то, что вы можете сделать с GPars, но как мне сделать это gradle с FileTree?

task compressJs(dependsOn: [copyJsToBuild]) << {
    println 'Minifying JS'

    fileTree {
        from 'build/js'
        include '**/*.js'
    }.visit { element ->
        if (element.file.isFile()) {
            println "Minifying ${element.relativePath}"
            ant.java(jar: "lib/yuicompressor-2.4.6.jar", fork: true) {
                arg(value: "build/js/${element.relativePath}")
                arg(value: "-o")
                arg(value: "build/js/${element.relativePath}")
            }
        }
    }
}

Было бы замечательно, если бы я мог сделать что-то вроде.visit{}.async(wait:true), но мой поиск в Google ничего не дал.Есть ли способ, которым я могу легко сделать это многопоточным?Обработка одного элемента не влияет на обработку любого другого элемента.

Ответы [ 2 ]

3 голосов
/ 01 сентября 2011

Прежде чем думать о переходе к многопоточности, я бы попробовал следующее:

  • Запустить все в одной и той же JVM.Создание новой JVM для каждого входного файла очень неэффективно.
  • Сделать задачу compressJs инкрементной, чтобы она выполнялась только в том случае, если какой-либо входной файл изменился с момента предыдущего запуска.чем через Ant (сохраняет создание нового загрузчика классов для каждого входного файла; не уверен, имеет ли это значение).

Если это все еще оставляет вас недовольными производительностью, и вы не можете использовать болееминимизатор производительности, вы все равно можете попробовать перейти на многопоточный.Gradle там вам пока не поможет, но библиотеки, такие как GPars или Java Fork / Join Framework, помогут.

1 голос
/ 02 сентября 2011

Решение GPars. Обратите внимание, что функцию compress() можно изменить, чтобы она правильно принимала исходный каталог / целевой каталог / и т. Д., Но поскольку все мои имена совпадают, я пока что использую только один аргумент. Я смог сократить время сборки с 7.3s до 5.4s, сохранив только 3 файла. Я видел, как время сборки выходит из-под контроля, поэтому я всегда опасаюсь производительности при таком поведении.

import groovyx.gpars.GParsPool

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'org.codehaus.gpars:gpars:0.12'
    }
}

def compress(String type) {
    def elementsToMinify = []
    fileTree {
        from type
        include "**/*.$type"
    }.visit { element ->
        if (element.file.isFile()) {
            elementsToMinify << element
        }
    }

    GParsPool.withPool(8) {
        elementsToMinify.eachParallel { element ->
            println "Minifying ${element.relativePath}"
            def outputFileLocation = "build/$type/${element.relativePath}"
            new File(outputFileLocation).parentFile.mkdirs()
            ant.java(jar: "lib/yuicompressor-2.4.6.jar", fork: true) {
                arg(value: "$type/${element.relativePath}")
                arg(value: "-o")
                arg(value: outputFileLocation)
            }
        }
    }
}

task compressJs {
    inputs.dir new File('js')
    outputs.dir new File('build/js')

    doLast {
        compress('js')
    }
}

task compressCss {
    inputs.dir new File('css')
    outputs.dir new File('build/css')

    doLast {
       compress('css')
    }
}
...