与 Kotlin 中的协程文件集进行比较

Compare to sets of files with coroutines in Kotlin

我写了一个函数,可以从两个列表中扫描文件(图片),并检查一个文件是否在两个列表中。

下面的代码按预期工作,但对于大型集合来说需要一些时间。所以我尝试与协程并行执行此操作。但是在 100 个示例文件的集合中,程序总是比没有协同程序慢。

代码:

private fun doJob()  {
    val filesToCompare = File("C:\Users\Tobias\Desktop\Test").walk().filter { it.isFile }.toList()
    val allFiles = File("\\myserver\Photos\photo").walk().filter { it.isFile }.toList()

    println("Files to scan: ${filesToCompare.size}")

    filesToCompare.forEach { file ->
        var multipleDuplicate = 0
        var s = "This file is a duplicate"
        s += "\n${file.absolutePath}"
        allFiles.forEach { possibleDuplicate ->
            if (file != possibleDuplicate) { //only needed when both lists are the same
                // Files that have the same name or contains the name, so not every file gets byte comparison
                if (possibleDuplicate.nameWithoutExtension.contains(file.nameWithoutExtension)) {
                    try {
                        if (Files.mismatch(file.toPath(), possibleDuplicate.toPath()) == -1L) {
                            s += "\n${possibleDuplicate.absolutePath}"
                            i++
                            multipleDuplicate++

                            println(s)
                        }
                    } catch (e: Exception) {
                        println(e.message)
                    }
                }
            }
        }
        if (multipleDuplicate > 1) {
            println("This file has $multipleDuplicate duplicate(s)")
        }
    }

    println("Files scanned: ${filesToCompare.size}")
    println("Total number of duplicates found: $i")
}

我是如何尝试添加协程的?

我将代码包装在 launch{...} 中的第一个 forEach 中,想法是为每个文件启动一个协程,并同时完成第二个循环。我预计该程序会 运行 更快,但实际上它是大约相同的时间或更慢。

如何才能更快地将此代码并行 运行?

运行 协程中的每个内部循环似乎都是一种不错的方法。问题可能出在您使用的调度程序上。如果您在没有上下文参数的情况下使用 runBlockinglaunch,则您使用的是单个线程 运行 所有协程。

由于这里主要是阻塞 IO,您可以改为使用 Dispatchers.IO 来启动您的协程,这样您的协程就会在多个线程上分派。并行度应自动限制为 64,但如果您的内存无法处理,您也可以使用 Dispatchers.IO.limitedParallelism(n) 来减少线程数。