FileTree文件的异步操作?

发布于 2024-12-02 07:07:07 字数 802 浏览 1 评论 0原文

有没有一种方法可以轻松地在 gradle 任务中以智能方式处理 FileTree 文件?我基本上需要等待所有文件的执行,就像使用 GPars 所做的那样,但是如何使用 FileTree 执行此 gradle 操作?

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) 的事情那就太好了,但我的谷歌搜索什么也没找到。有没有办法可以轻松地使其成为多线程?一个元素的处理不会影响任何其他元素的处理。

Is there a way I can easily make the processing of FileTree files in a smart way in gradle tasks? I basically need to wait for the execution of all files, much like what you can do with GPars, but how do I do this gradle with 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}")
            }
        }
    }
}

It would be lovely if I could do something like .visit{}.async(wait:true), but my googling turned up nothing. Is there a way I can easily make this multi-threaded? The processing of one element has no effect on the processing of any other element.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

此岸叶落 2024-12-09 07:07:07

在考虑使用多线程之前,我会尝试以下操作:

  • 在同一个 JVM 中运行所有内容。为每个输入文件创建一个新的 JVM 效率非常低。
  • 使 compressJs 任务增量,以便仅在某些输入文件自上次运行以来发生更改时才执行。
  • 直接运行压缩器而不是通过 Ant 运行(节省为每个输入文件创建新的类加载器;不确定这是否重要)。

如果这仍然让您对性能不满意,并且您无法使用性能更高的压缩器,那么您仍然可以尝试使用多线程。 Gradle 还无法在这方面为您提供帮助,但 GPars 或 Java Fork/Join 框架等库可以。

Before thinking about going multi-threaded, I'd try the following:

  • Run everything in the same JVM. Forking a new JVM for each input file is very inefficient.
  • Make the compressJs task incremental so that it only executes if some input file has changed since the previous run.
  • Run the minifier directly rather than via Ant (saves creation of a new class loader for each input file; not sure if it matters).

If this still leaves you unhappy with the performance, and you can't use a more performant minifier, you can still try to go multi-threaded. Gradle won't help you there (yet), but libraries like GPars or the Java Fork/Join framework will.

浮生面具三千个 2024-12-09 07:07:07

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')
    }
}

The GPars solution. Note that the compress() function could be modified to properly accept source dir/target dir/etc, but since all my names are consistent, I'm just using the one argument for now. I was able to cut my build time from 7.3s to 5.4s with only 3 files being minified. I've seen build times spiral out of control, so I'm always wary of performance with this kind of behavior.

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')
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文