Java: первая итерация цикла for занимает больше времени
Я пишу код для тестирования с использованием библиотек MIDI в Java, и столкнулся с проблемой. Пауза между нотами намного длиннее (фактически вдвое длиннее) после самой первой ноты, чем после всех остальных. Я не вижу причин, по которым, поскольку последовательность нот уже сгенерирована (следовательно, эти вычисления также не нужно выполнять в течение первой итерации цикла, это только воспроизведение нот).
Я думаю, что у меня, возможно, также была эта проблема в прошлом с моделированием, которое, без какого-либо объяснения, которое я мог найти, занимало почти 100% его длины тика для выполнения вычислений только на первом тике, а затем использовало только около 2% на всех последовательные итерации.
Основной код (извлечение):
public void play() {
MidiPlayer player = new MidiPlayer();
for (int i = 0; i < NUMNOTES; i++) {
long tic = System.currentTimeMillis();
player.playNote(10, notes[i]);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
long toc = System.currentTimeMillis();
System.out.println(toc - tic);
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Код для playNote():
public void playNote(int channel, int note) {
channels[channel].allNotesOff();
channels[channel].noteOn(note + 60, volume);
}
Нет операторов if, которые определяют первый цикл, поэтому, несомненно, задержка должна быть одинаковой для всех примечаний, так как количество выполняемых вычислений должно быть одинаковым для всех итераций. Обратите внимание, что временные переменные предназначены только для тестирования, и эффект был слышен до того, как я их включил.
РЕДАКТИРОВАТЬ: я должен также упомянуть, что полученный вывод показывает каждую итерацию цикла, занимающего ожидаемые 200 (иногда 201) миллисекунд. Кажется, это говорит о том, что пробела нет - но каждый раз, когда я запускаю код, я четко слышу пробел.
0 ответов
Поскольку у вас есть сны, вы должны рассчитать, сколько вы должны спать, вместо того, чтобы пытаться спать одно и то же время каждый раз - рассчитать, сколько на самом деле вам нужно времени, чтобы сыграть следующую ноту, и поспать столько же времени. т.е.
long tic = System.currentTimeMillis();
player.playNote(10, notes[i]);
long time_spent = System.currentTimeMillis() - tic;
Thread.sleep(200 - time_spent);