В моем приложении для телефона Android есть много больших списков поплавков (100000+). Чтобы использовать их с OpenGl, списки преобразуются в FloatArrays, а затем в байтовые буферы. У меня возникли проблемы с производительностью, и спустя много часов кажется, что функция Kotlin .toFloatArray () работает очень медленно.
Некоторые результаты теста на моем телефоне Samsung Galaxy:
elapsed time(msec) time/float(microsec)
max min avg
fillFloatArray 70 39 59,7 6.0
fillFloatList 472 357 444,1 44.4
convertListToArrayLooping 165 101 155,2 15.5
convertWithToFloatArray 388 318 367,3 36.7
Number of floats 10000
runs 10
(the average time / float is the same for a list of 100000 floats)
Заполнение floatarray значениями происходит быстро, а заполнение списка с помощью float - в 7,4 раза медленнее.
Однако преобразование List в floatarray с помощью стандартной функции List.toFoatArray () в 6,1 раза медленнее, чем простое заполнение массива, также 2,4 раза медленнее , чем циклическое повторение список. Это почти так же медленно, как заполнение пустого Списка с помощью Floats!
Я ожидал, что время преобразования будет ближе ко времени простого заполнения массива?
Имеет ли смысл выполнение .toFloatArray ()? И какой самый быстрый или, по крайней мере, более быстрый способ преобразования списка в байтбуфер?
Под небольшой тестовой программой, для справки.
class PlayGround {
private val stopwatch = Timing()
private val arraylist: MutableList<Float> = arrayListOf()
private val fillFloatArray = Results()
private val fillFloatList = Results()
private val convertListToArrayLooping = Results()
private val convertWithToFloatArray = Results()
fun checkSpeed () {
for (i in 0 until 10) { // do the timing ten times to get an average
// filling a floatarray with 10000 floats
stopwatch.start()
var array = FloatArray(10000, { it * 1f })
fillFloatArray.add(stopwatch.stop())
// filling a list with 10000 floats
stopwatch.start()
for (i in 0 until 10000) {
arraylist.add(i * 1f)
}
fillFloatList.add(stopwatch.stop())
// converting the fulllist to a floatarray by looping
stopwatch.start()
for (i in 0 until arraylist.size) {
array[i] = arraylist[i]
}
convertListToArrayLooping.add(stopwatch.stop())
// converting the fullist to a floatarray with toFloatArray
stopwatch.start()
array = arraylist.toFloatArray()
convertWithToFloatArray.add(stopwatch.stop())
arraylist.clear()
}
}
private class Results {
private var max = Long.MIN_VALUE
private var min = Long.MAX_VALUE
private var sum = 0L
private var avg = 0L
var measurePoints: MutableList<Long> = arrayListOf()
fun add (msrp: Long) {
measurePoints.add(msrp)
if (msrp > max) max = msrp
if (msrp < min) min = msrp
sum += msrp
avg = sum / measurePoints.size
}
fun clear() {
measurePoints.clear()
max = Long.MIN_VALUE
min = Long.MAX_VALUE
sum = 0L
avg = 0L
}
fun max(): Long { return max}
fun min(): Long { return min}
fun sum(): Long { return sum}
fun avg(): Long { return avg}
}
}