0xDEADBEEF

[RSS]
««« »»»

Porovnání Javy a Scaly v porovnávání

20. 12. 2019

Do Scaly verze 3, vy­ví­jené jako pro­jekt dotty, se možná do­stane ex­pli­citní nullo­vost pro­měn­ných.

var x: String      // nemůže být null
var x: String|Null // může být null

Ode­r­sky a jeho gang tak chtějí ode­sek­nout pár drob­ných z Ho­a­rova omylu za mi­li­ardu dolarů a eli­mi­no­vat tolik otrav­ných NPE, jak jen bude možné. Nabízí se ale jedna další otázka: Zrychlí to vý­sledný pro­gram?

Může.

Ve Scale má po­rov­nání na sta­rosti ope­rá­tor ==, který se chová jako equals() v Javě s jed­ni­nou vý­jim­kou: null == x ne­vy­hodí NPE jako null.equals(x). Scala tedy musí při po­rov­nání pro­vá­dět jednu kon­t­rolu navíc.

Z metoda ob­sa­hu­jící jen x.equals("xxx") javac vy­ge­ne­ruje tento by­te­kód:

0: aload_1
1: ldc           #2                  // String xxx
3: invokevirtual #3                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
6: ireturn

A tuhle mon­stro­zitu x == "xxx" vy­plodí scalac:

0: aload_1
1: ldc           #12                 // String xxx
3: astore_2
4: dup
5: ifnonnull     16
8: pop
9: aload_2
10: ifnull        23
13: goto          27
16: aload_2
17: invokevirtual #16                 // Method java/lang/Object.equals:(Ljava/lang/Object;)Z
20: ifeq          27
23: iconst_1
24: goto          28
27: iconst_0
28: ireturn

S pře­pí­na­čem -optimize je vý­sledný by­te­kód o něco menší, ale pořád delší než pro­dukt javac.

JIT je velice efek­tivní v op­ti­ma­li­zač­ních kouz­lech, proto ne­zá­leží jak to vypadá, ale jaký je reálný dopad na re­ál­nou rych­lost na re­ál­ném stroji.

Benchmark         Score   Error  Units
EqJava.strEqVar   6,162 ± 0,003  ns/op  // "xxx".equals(str)
EqJava.varEqStr   6,163 ± 0,009  ns/op  // str.equals("xxx")
EqScala.strEqVar  6,935 ± 0,014  ns/op  // "xxx" == str
EqScala.varEqStr  6,934 ± 0,010  ns/op  // str == "xxx"

Rozdíl je malý, ale přesto vi­di­telný. Takže když se o pro­měnné ví, že nemůže být null, == ope­rá­tor může vy­ge­ne­ro­vat jed­no­dušší a o něco málo rych­lejší by­te­kód.

píše k47 (@kaja47, k47)