Я пытаюсь использовать синхронизированный блок java с использованием ASM. Проблема в том, что после инструментария время выполнения синхронизированного блока занимает больше времени. Здесь он увеличивается с 2 мсек до 200 мсек в ящике Linux.Синхронизированный блок занимает больше времени после работы с ASM
Я реализую это, идентифицируя код операции MonitorEnter и MonitorExit.
Я пытаюсь использовать инструмент на трех уровнях 1. непосредственно перед MonitorEnter 2. после MonitorEnter 3. Перед MonitorExit. 1 и 3 вместе работают нормально, но когда я делаю 2, время выполнения резко возрастает.
Даже если мы применяем еще одну инструкцию SOP, которая предназначена для выполнения только один раз, она дает более высокие значения. Вот пример кода (простое число, 10 петель):
for(int w=0;w<10;w++){
synchronized(s){
long t1 = System.currentTimeMillis();
long num = 2000;
for (long i = 1; i < num; i++) {
long p = i;
int j;
for (j = 2; j < p; j++) {
long n = p % i;
}
}
long t2 = System.currentTimeMillis();
System.out.println("Time>>>>>>>>>>>> " + (t2-t1));
}
Вот код для instrumention (здесь System.currentMilliSeconds() дает время, при котором произошло instrumention, его не в меру времени выполнения, то excecution время от obove заявления СОП):
public void visitInsn(int opcode)
{
switch(opcode)
{
// Scenario 1
case 194:
visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io /PrintStream;");
visitLdcInsn("TIME Arrive: "+System.currentTimeMillis());
visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
break;
// scenario 3
case 195:
visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
visitLdcInsn("TIME exit : "+System.currentTimeMillis());
visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
break;
}
super.visitInsn(opcode);
// scenario 2
if(opcode==194)
{
visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
visitLdcInsn("TIME enter: "+System.currentTimeMillis());
visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
}
}
Я не могу найти причину, почему это происходит и как это исправить т.
Заранее благодарен.
Вы не измеряете саму синхронизацию, так как вызовы 'currentTimeMillis' находятся в синхронизированном блоке. Кстати, что такое '' '? Какие знания о конфликте происходят при синхронизации на этом объекте? – Holger
** s ** - объект String, по которому выполняется синхронизация. здесь я использую только один поток, а блок синхронизации работает 10 раз. Каждое время (t2-t1) вычисляется. Я использую currentTimeMillis внутри блока bcoz, это время обслуживания этого блока, которое одинаково для всех потоков. Это мой мотив, почему он так сильно растет после инструментария. Пожалуйста, не задумывайтесь об этом сейчас. По крайней мере, время выполнения должно оставаться неизменным. – user3032258
Вы измеряете способность JVM оптимизировать неиспользуемый/бессмысленный код, и кажется, что добавление оператора печати (эффект видимого снаружи) в определенном месте нарушает оптимизацию. Кстати, 'String' является необычным объектом для синхронизации. Не рекомендуется. – Holger