Kotlin i.inc () 10x медленнее, чем i ++?

Поэтому сегодня я узнал о функции num.inc () в kotlin и решил реализовать ее в своем коде. Излишне говорить, что добавлено 10-кратное время ожидания для моего кода (от ~ 400 мс до 4000 + мс)

Вот пример с моим традиционным способом (i ++, 400ms)

package com.beaudoin import java.io.BufferedWriter import java.io.FileInputStream import java.io.FileWriter import java.nio.channels.FileChannel fun main(args: Array<String>) { val s = System.currentTimeMillis() val channel = FileInputStream("client.dll").channel val buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()) val data = ByteArray(buffer.capacity()) buffer.get(data) val writer = BufferedWriter(FileWriter("dump.txt", false)) val bytes = ByteArray(16) var offset = 0 var i = 0 while (i < data.size) { for (j in bytes.indices) { bytes[j] = data[i++] } writer.write(HexRow(offset, bytes).toString()) writer.newLine() offset += 16 } writer.close() println(System.currentTimeMillis() - s) } private val HEX_ARRAY = "0123456789ABCDEF".toCharArray() private val bytes = ByteArray(4); class HexRow(val offset: Int, val values: ByteArray) { fun bytesToChar(bytes: ByteArray, width: Int): CharArray { val hexChars = CharArray((bytes.size * 2) + (bytes.size / width)) for (i in bytes.indices) { val v = bytes[i].toInt() and 0xFF val idx = (i * 2) + i / width hexChars[idx] = HEX_ARRAY[v.ushr(4)] hexChars[idx + 1] = HEX_ARRAY[v and 0x0F] if (idx + 2 < hexChars.size) { hexChars[idx + 2] = ' ' } } return hexChars; } fun bytesToHex(value: Int) = String(bytesToChar(toByteArray(value), 6)) fun bytesToHex(bytes: ByteArray) = String(bytesToChar(bytes, 1)) fun toByteArray(value: Int): ByteArray { bytes[0] = value.ushr(24).toByte() bytes[1] = value.ushr(16).toByte() bytes[2] = value.ushr(8).toByte() bytes[3] = value.toByte() return bytes } override fun toString() = bytesToHex(offset) + " " + bytesToHex(values) } 

и вот код с использованием i.inc () (4000ms +)

 package com.beaudoin import java.io.BufferedWriter import java.io.FileInputStream import java.io.FileWriter import java.nio.channels.FileChannel fun main(args: Array<String>) { val s = System.currentTimeMillis() val channel = FileInputStream("client.dll").channel val buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()) val data = ByteArray(buffer.capacity()) buffer.get(data) val writer = BufferedWriter(FileWriter("dump.txt", false)) val bytes = ByteArray(16) var offset = 0 /* var i = 0 while (i < data.size) { for (j in bytes.indices) { bytes[j] = data[i++] } writer.write(HexRow(offset, bytes).toString()) writer.newLine() offset += 16 }*/ for (i in data.indices) { for (j in bytes.indices) { bytes[j] = data[i] i.inc() } writer.write(HexRow(offset, bytes).toString()) writer.newLine() offset += 16 } writer.close() println(System.currentTimeMillis() - s) } private val HEX_ARRAY = "0123456789ABCDEF".toCharArray() private val bytes = ByteArray(4); class HexRow(val offset: Int, val values: ByteArray) { fun bytesToChar(bytes: ByteArray, width: Int): CharArray { val hexChars = CharArray((bytes.size * 2) + (bytes.size / width)) for (i in bytes.indices) { val v = bytes[i].toInt() and 0xFF val idx = (i * 2) + i / width hexChars[idx] = HEX_ARRAY[v.ushr(4)] hexChars[idx + 1] = HEX_ARRAY[v and 0x0F] if (idx + 2 < hexChars.size) { hexChars[idx + 2] = ' ' } } return hexChars; } fun bytesToHex(value: Int) = String(bytesToChar(toByteArray(value), 6)) fun bytesToHex(bytes: ByteArray) = String(bytesToChar(bytes, 1)) fun toByteArray(value: Int): ByteArray { bytes[0] = value.ushr(24).toByte() bytes[1] = value.ushr(16).toByte() bytes[2] = value.ushr(8).toByte() bytes[3] = value.toByte() return bytes } override fun toString() = bytesToHex(offset) + " " + bytesToHex(values) } 

Может кто-нибудь, пожалуйста, скажите мне, почему i.inc () намного медленнее, чем i ++?

PS: Замените client.dll любым файлом (должно быть ~ 12mb, чтобы получить точные цифры или просто загрузить здесь тестовый файл здесь

inc() в вашем коде полностью избыточно: он не меняет переменную:

 var x = 0 x.inc() println(x) // 0 

Что касается разницы во времени выполнения, то даже семантика двух реализаций различна:

  • Первый фрагмент:

     while (i < data.size) { for (j in bytes.indices) { bytes[j] = data[i++] } //... } 

    Внутренний цикл изменяет i , поэтому не будет итерации while для каждого i , некоторые (даже большинство, я полагаю) значения i будут пропущены.

  • Второй фрагмент:

     for (i in data.indices) { for (j in bytes.indices) { bytes[j] = data[i] // removed redundant i.inc() } //... } 

    Внутренний цикл вызывается для каждого i во внешнем цикле, поэтому потребуется гораздо больше времени.