我有一个奇怪的问题,我发现运行并发 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 代码相同的性能。
添加回答
举报
0/150
提交
取消