为了账号安全,请及时绑定邮箱和手机立即绑定

与 Java 相比,Kotlin 中并发 shell 命令的性能较差

与 Java 相比,Kotlin 中并发 shell 命令的性能较差

qq_花开花谢_0 2021-09-29 13:30:55
我有一个奇怪的问题,我发现运行并发 shell 命令以提取文件的 Kotlin 代码性能非常差。但是,当使用 Java 代码运行相同的 shell 命令时,性能符合预期。差异非常显着,Java 代码运行时间为 10-20 秒,而 Kotlin 代码运行时间约为 13 分钟。特定用例是一个产生 15 个线程的函数,所有线程都调用此提取函数来解压相同的 tar.gz 文件。调用Kotlin函数时,性能较差;当它是Java时,性能如预期。我反编译为 Java 的 Kotlin 代码与性能良好的 Java 代码几乎相同,唯一的区别是添加了 Kotlin Intrinsics,这应该不会影响性能。科特林代码:@Synchronized@Throws(IOException::class)fun extractTar(tarFile: Path, extractPath: Path) {    logger.info("Extracting file: " + tarFile.toString())    logger.info("Destination path: " + extractPath.toString())    val start = System.currentTimeMillis()    val untarCommand = Arrays.asList("tar", "-xzf", tarFile.toString(), "-C", extractPath.toString())    val untarProcess = ProcessBuilder()            .command(untarCommand)            .redirectErrorStream(true)            .start()    waitAndCheckProcessOutput(untarProcess, "tar -xzf ${tarFile.toString()} -C ${extractPath.toString()}", 15)    logger.info("Running chmod on folder:" + extractPath.toString())    val chmodCommand = Arrays.asList("chmod", "-R", "0777", extractPath.toString())    val chmodProcess = ProcessBuilder()            .command(chmodCommand)            .redirectErrorStream(true)            .start()    waitAndCheckProcessOutput(chmodProcess, "chmod -R 0777 ${extractPath.toString()}", 15)    logger.info("Extracted in " + printTime(System.currentTimeMillis() - start))}它是这样调用的:IntStream.range(0, count).parallel().forEach{ unsynchronizedMethod() }在此 unsynchronizedMethod 中调用 extractTar 的地方。我 95% 确定在 Intrinsic 库调用中不会发生减速,因为检查的值都不应该为空。还有趣的是,对于少量线程,例如2个线程不会发生减速。随着线程数的增加,性能下降,这让我怀疑这实际上是并发问题。我还尝试运行 Kotlin-decompiled-to-Java 代码,去除 Intrinsic 库调用,并且该代码具有与本机 Java 代码相同的性能。
查看完整描述

1 回答

?
慕容森

TA贡献1853条经验 获得超18个赞

通过将提取物移入固定

companion object {}

不知道为什么这解决了问题,但确实如此


查看完整回答
反对 回复 2021-09-29
  • 1 回答
  • 0 关注
  • 373 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信