Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Поиск причин необычной продуктивности

Anna | 2.06.2014 | нет комментариев

Вступление

Наконец-то полез подробно постигать Java-байткод, и примерно сразу же в голове появился увлекательный вопрос. Есть там инструкция NOP, которая не делает ничего. Так вот, а как это «ничего» сказывается на продуктивности? Собственно, процесс постижения этого и описан в посте.

Дисклеймер

Сам рассказ, в первую очередь, не о том, как оно реально работает, а о том, каких ошибок стоит бояться при измерениях продуктивности.

Инструменты

Начнем с основного: как проводились все измерения. Для генерации кода применялась библиотека ASM, для создания самого бенчмарка — JMH.

Дабы не применять reflection, был сделан небольшой интерфейс:

public interface Getter {
    int get();
}

Дальше, генерировался класс, реализующий способ get:

  public get()I
    NOP
    ...
    NOP
    LDC 20
    IRETURN

Дозволено вставить произвольное число нопов.

Полный код генератора

public class SimpleGetterClassLoader extends ClassLoader {

    private static final String GENERATED_CLASS_NAME = "other.GeneratedClass";

    private static final ClassLoader myClassLoader = new SimpleGetterClassLoader();

    @SuppressWarnings("unchecked")
    public static Getter newInstanceWithNOPs(int nopCount) throws Exception {
        Class<?> clazz = Class.forName(GENERATED_CLASS_NAME   "_"   nopCount, false, myClassLoader);
        return (Getter) clazz.newInstance();
    }

    @NotNull
    @Override
    protected Class<?> findClass(@NotNull String name) throws ClassNotFoundException {
        if (!name.startsWith(GENERATED_CLASS_NAME))
            throw new ClassNotFoundException(name);

        int nopCount = Integer.parseInt(name.substring(GENERATED_CLASS_NAME.length()   1));

        ClassWriter cw = new ClassWriter(0);
        cw.visit(V1_5, ACC_PUBLIC, name.replace('.', '/'), null, getInternalName(Object.class), new String[]{getInternalName(Getter.class)});
        {
            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
            mv.visitCode();
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKESPECIAL, getInternalName(Object.class), "<init>", "()V");
            mv.visitInsn(RETURN);
            mv.visitMaxs(1, 1);
            mv.visitEnd();
        }
        {
            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "get", "()I", null, null);
            mv.visitCode();
            for (int i = 0; i < nopCount; i  ) {
                mv.visitInsn(NOP);
            }
            mv.visitLdcInsn(20);
            mv.visitInsn(IRETURN);
            mv.visitMaxs(1, 1);
            mv.visitEnd();
        }
        cw.visitEnd();

        byte[] bytes = cw.toByteArray();

        return defineClass(name, bytes, 0, bytes.length);
    }
}

 

Бенчмарк

@State(Scope.Benchmark)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public class Bench {

    private Getter nop_0;
    private Getter nop_10;
    ...

    @Setup
    public void setup() throws Exception {
        nop_0 = newInstanceWithNOPs(0);
        nop_10 = newInstanceWithNOPs(10);
        ...
    }

    @GenerateMicroBenchmark
    public int nop_0() {
        return nop_0.get();
    }

    @GenerateMicroBenchmark
    public int nop_10() {
        return nop_10.get();
    }

   ...

Поиск истины

Вначале были запущены 2 теста: без нопов и с 2000.

Benchmark            Mode   Samples         Mean   Mean error    Units
b.Bench.nop_0       thrpt         5      838,753       48,962   ops/us
b.Bench.nop_2000    thrpt         5      298,428        7,965   ops/us

И сразу же я сделал дюже сильный итог: «Тупой JIT не вырезает нопы, а транслирует их в машинные.»

Вопрос знатокам:

Если бы это было правдой, то итог измерения был бы схож? Либо было бы что-то абсолютно другое?

Но это, все-таки, была догадка, и дюже хотелось ее проверить. Вначале удостоверился что эти способы подлинно компилируются JIT`ом.

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB