Graal: Unexpected more than 10x slowdown with Scala.js

Created on 12 May 2020  路  3Comments  路  Source: oracle/graal

  • GraalVM version: 20.0.0 and 20.2.0-dev
  • CE or EE: both
  • JDK version: tested with JDK8 only
  • OS and OS Version: macOS Mojave, Ubuntu 18.04
  • Architecture: amd64

Steps to reproduce the issue:

  1. git clone --depth 1 https://github.com/plokhotnyuk/jsoniter-scala
  2. cd jsoniter-scala
  3. sbt 'jsoniter-scala-coreJS/testOnly *JsonWriterSpec' using of OpenJDK and the original Node.JS
  4. sbt -java-home /usr/lib/jvm/graalvm-ce-java8 'jsoniter-scala-coreJS/testOnly *JsonWriterSpec'
    (or export PATH=/usr/lib/jvm/graalvm-ce-java8/jre/languages/js/bin:$PATH and then the command from 3rd step)
  5. sbt -java-home /usr/lib/jvm/graalvm-ee-java8 'jsoniter-scala-coreJS/testOnly *JsonWriterSpec' (or export PATH=/usr/lib/jvm/graalvm-ee-java8/jre/languages/js/bin:$PATH and then the command from 3rd step)

The expected behavior is completing the test suite in ~20 seconds as with the stable version of the original Node.js, but the embedded to GraalVM version of Node.js is completing the suite in ~5.5 minutes with GraalVM CE or ~3.5 minutes with GraalVM EE.

Results on Ubuntu 18.04

andriy@notebook:~/Projects/com/github/plokhotnyuk/jsoniter-scala$ node -v
v12.16.3
andriy@notebook:~/Projects/com/github/plokhotnyuk/jsoniter-scala$ sbt 'jsoniter-scala-coreJS/testOnly *JsonWriterSpec'
[info] Loading global plugins from /home/andriy/.sbt/1.0/plugins
[info] Loading settings for project jsoniter-scala-build from plugins.sbt ...
[info] Loading project definition from /home/andriy/Projects/com/github/plokhotnyuk/jsoniter-scala/project
[info] Loading settings for project jsoniter-scala from release.sbt,build.sbt,version.sbt ...
[info] Set current project to jsoniter-scala (in build file:/home/andriy/Projects/com/github/plokhotnyuk/jsoniter-scala/)
[info] JsonWriterSpec:
[info] WriterConfig.<init>
[info] - should have handy defaults (3 milliseconds)
[info] - should throw exception in case for unsupported values of params (0 milliseconds)
[info] JsonWriter.isNonEscapedAscii
[info] - should return false for all escaped ASCII or non-ASCII chars (285 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and and JsonWriter.writeKey for boolean
[info] - should write valid true and false values (2 milliseconds)
[info] JsonWriter.writeNonEscapedAsciiVal and JsonWriter.writeNonEscapedAsciiKey
[info] - should don't write null value (1 millisecond)
[info] - should write string of Ascii chars which should not be escaped (727 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for UUID
[info] - should don't write null value (1 millisecond)
[info] - should write UUID as a string representation according to format that defined in IETF RFC4122 (section 3) (268 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for Duration
[info] - should don't write null value (0 milliseconds)
[info] - should write Duration as a string representation according to ISO-8601 format (201 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for Instant
[info] - should don't write null value (1 millisecond)
[info] - should write Instant as a string representation according to ISO-8601 format (414 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for LocalDate
[info] - should don't write null value (0 milliseconds)
[info] - should write LocalDate as a string representation according to ISO-8601 format (173 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for LocalDateTime
[info] - should don't write null value (0 milliseconds)
[info] - should write LocalDateTime as a string representation according to ISO-8601 format (247 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for LocalTime
[info] - should don't write null value (0 milliseconds)
[info] - should write LocalTime as a string representation according to ISO-8601 format (133 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for MonthDay
[info] - should don't write null value (0 milliseconds)
[info] - should write MonthDay as a string representation according to ISO-8601 format (102 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for OffsetDateTime
[info] - should don't write null value (0 milliseconds)
[info] - should write OffsetDateTime as a string representation according to ISO-8601 format (300 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for OffsetTime
[info] - should don't write null value (1 millisecond)
[info] - should write OffsetTime as a string representation according to ISO-8601 format (198 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for Period
[info] - should don't write null value (1 millisecond)
[info] - should write Period as a string representation according to ISO-8601 format (184 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for Year
[info] - should don't write null value (0 milliseconds)
[info] - should write Year as a string representation according to ISO-8601 format (114 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for YearMonth
[info] - should don't write null value (0 milliseconds)
[info] - should write YearMonth as a string representation according to ISO-8601 format (120 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for ZonedDateTime
[info] - should don't write null value (0 milliseconds)
[info] - should write ZonedDateTime as a string representation according to ISO-8601 format with optional IANA timezone identifier in JDK 8+ format (1 second, 30 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for ZoneOffset
[info] - should don't write null value (0 milliseconds)
[info] - should write ZoneOffset as a string representation according to ISO-8601 format (90 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for ZoneId
[info] - should don't write null value (0 milliseconds)
[info] - should write ZoneId as a string representation according to ISO-8601 format for timezone offset or JDK 8+ format for IANA timezone identifier (568 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for string
[info] - should don't write null value (1 millisecond)
[info] - should write string of Unicode chars which are non-surrogate and should not be escaped (931 milliseconds)
[info] - should write strings with chars that should be escaped (1 second, 476 milliseconds)
[info] - should write strings with escaped Unicode chars when it is specified by provided writer config (1 second, 599 milliseconds)
[info] - should write strings with valid character surrogate pair (246 milliseconds)
[info] - should write string with mixed Latin-1 characters when escaping of Unicode chars is turned on (1 millisecond)
[info] - should write string with mixed UTF-8 characters when escaping of Unicode chars is turned off (0 milliseconds)
[info] - should throw i/o exception in case of illegal character surrogate pair (994 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for char
[info] - should write string with Unicode chars which are non-surrogate or should not be escaped (102 milliseconds)
[info] - should write string with chars that should be escaped (229 milliseconds)
[info] - should write string with escaped Unicode chars when it is specified by provided writer config (123 milliseconds)
[info] - should throw i/o exception in case of surrogate pair character (2 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for byte
[info] - should write any short values (24 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for short
[info] - should write any short values (111 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for int
[info] - should write any int values (110 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for long
[info] - should write any long values (248 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for float
[info] - should write finite float values (642 milliseconds)
[info] - should write float values exactly as expected (1 millisecond)
[info] - should write round-even float values (1 millisecond)
[info] - should throw i/o exception on non-finite numbers (1 millisecond)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for double
[info] - should write finite double values (787 milliseconds)
[info] - should write double values exactly as expected (0 milliseconds)
[info] - should write round-even double values (0 milliseconds)
[info] - should throw i/o exception on non-finite numbers (2 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for BigInt
[info] - should don't write null value (1 millisecond)
[info] - should write number values (3 seconds, 486 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for BigDecimal
[info] - should don't write null value (1 millisecond)
[info] - should write number values (2 seconds, 503 milliseconds)
[info] JsonWriter.writeBase16Val
[info] - should don't write null value (1 millisecond)
[info] - should write bytes as Base16 string according to format that defined in RFC4648 (1 second, 846 milliseconds)
[info] JsonWriter.writeBase64Val and JsonWriter.writeBase64UrlVal
[info] - should don't write null value (1 millisecond)
[info] - should write bytes as Base64 string according to format that defined in RFC4648 (1 second, 288 milliseconds)
[info] JsonWriter.writeRawVal
[info] - should don't write null value (1 millisecond)
[info] - should write raw bytes as is (753 milliseconds)
[info] JsonWriter.writeNull
[info] - should write null value (0 milliseconds)
[info] JsonWriter.writeArrayStart and JsonWriter.writeArrayEnd
[info] - should allow to write an empty JSON array (0 milliseconds)
[info] - should allow to write a compact JSON array with values separated by comma (1 millisecond)
[info] - should allow to write a prettified JSON array with values separated by comma (1 millisecond)
[info] JsonWriter.writeObjectStart and JsonWriter.writeObjectEnd
[info] - should allow to write an empty JSON object (1 millisecond)
[info] - should allow to write a compact JSON array with key/value pairs separated by comma (0 milliseconds)
[info] - should allow to write a prettified JSON array with key/value pairs separated by comma (0 milliseconds)
[info] ScalaTest
[info] Run completed in 22 seconds, 941 milliseconds.
[info] Total number of tests run: 77
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 77, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[info] Passed: Total 77, Failed 0, Errors 0, Passed 77
[success] Total time: 25 s, completed May 12, 2020 7:17:19 PM
andriy@notebook:~/Projects/com/github/plokhotnyuk/jsoniter-scala$ export PATH=/usr/lib/jvm/graalvm-ce-java8/jre/languages/js/bin:$PATH
andriy@notebook:~/Projects/com/github/plokhotnyuk/jsoniter-scala$ node -v
v12.15.0
andriy@notebook:~/Projects/com/github/plokhotnyuk/jsoniter-scala$ sbt 'jsoniter-scala-coreJS/testOnly *JsonWriterSpec'
[info] Loading global plugins from /home/andriy/.sbt/1.0/plugins
[info] Loading settings for project jsoniter-scala-build from plugins.sbt ...
[info] Loading project definition from /home/andriy/Projects/com/github/plokhotnyuk/jsoniter-scala/project
[info] Loading settings for project jsoniter-scala from release.sbt,build.sbt,version.sbt ...
[info] Set current project to jsoniter-scala (in build file:/home/andriy/Projects/com/github/plokhotnyuk/jsoniter-scala/)
[info] JsonWriterSpec:
[info] WriterConfig.<init>
[info] - should have handy defaults (5 milliseconds)
[info] - should throw exception in case for unsupported values of params (5 milliseconds)
[info] JsonWriter.isNonEscapedAscii
[info] - should return false for all escaped ASCII or non-ASCII chars (4 seconds, 221 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and and JsonWriter.writeKey for boolean
[info] - should write valid true and false values (9 milliseconds)
[info] JsonWriter.writeNonEscapedAsciiVal and JsonWriter.writeNonEscapedAsciiKey
[info] - should don't write null value (4 milliseconds)
[info] - should write string of Ascii chars which should not be escaped (15 seconds, 876 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for UUID
[info] - should don't write null value (4 milliseconds)
[info] - should write UUID as a string representation according to format that defined in IETF RFC4122 (section 3) (6 seconds, 644 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for Duration
[info] - should don't write null value (4 milliseconds)
[info] - should write Duration as a string representation according to ISO-8601 format (7 seconds, 317 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for Instant
[info] - should don't write null value (4 milliseconds)
[info] - should write Instant as a string representation according to ISO-8601 format (12 seconds, 123 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for LocalDate
[info] - should don't write null value (3 milliseconds)
[info] - should write LocalDate as a string representation according to ISO-8601 format (7 seconds, 385 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for LocalDateTime
[info] - should don't write null value (4 milliseconds)
[info] - should write LocalDateTime as a string representation according to ISO-8601 format (6 seconds, 999 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for LocalTime
[info] - should don't write null value (4 milliseconds)
[info] - should write LocalTime as a string representation according to ISO-8601 format (3 seconds, 427 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for MonthDay
[info] - should don't write null value (3 milliseconds)
[info] - should write MonthDay as a string representation according to ISO-8601 format (2 seconds, 540 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for OffsetDateTime
[info] - should don't write null value (3 milliseconds)
[info] - should write OffsetDateTime as a string representation according to ISO-8601 format (5 seconds, 689 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for OffsetTime
[info] - should don't write null value (3 milliseconds)
[info] - should write OffsetTime as a string representation according to ISO-8601 format (2 seconds, 668 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for Period
[info] - should don't write null value (3 milliseconds)
[info] - should write Period as a string representation according to ISO-8601 format (4 seconds, 696 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for Year
[info] - should don't write null value (3 milliseconds)
[info] - should write Year as a string representation according to ISO-8601 format (3 seconds, 130 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for YearMonth
[info] - should don't write null value (4 milliseconds)
[info] - should write YearMonth as a string representation according to ISO-8601 format (2 seconds, 958 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for ZonedDateTime
[info] - should don't write null value (2 milliseconds)
[info] - should write ZonedDateTime as a string representation according to ISO-8601 format with optional IANA timezone identifier in JDK 8+ format (19 seconds, 124 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for ZoneOffset
[info] - should don't write null value (3 milliseconds)
[info] - should write ZoneOffset as a string representation according to ISO-8601 format (1 second, 548 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for ZoneId
[info] - should don't write null value (4 milliseconds)
[info] - should write ZoneId as a string representation according to ISO-8601 format for timezone offset or JDK 8+ format for IANA timezone identifier (4 seconds, 52 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for string
[info] - should don't write null value (3 milliseconds)
[info] - should write string of Unicode chars which are non-surrogate and should not be escaped (13 seconds, 330 milliseconds)
[info] - should write strings with chars that should be escaped (15 seconds, 423 milliseconds)
[info] - should write strings with escaped Unicode chars when it is specified by provided writer config (8 seconds, 490 milliseconds)
[info] - should write strings with valid character surrogate pair (3 seconds, 934 milliseconds)
[info] - should write string with mixed Latin-1 characters when escaping of Unicode chars is turned on (2 milliseconds)
[info] - should write string with mixed UTF-8 characters when escaping of Unicode chars is turned off (2 milliseconds)
[info] - should throw i/o exception in case of illegal character surrogate pair (52 seconds, 709 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for char
[info] - should write string with Unicode chars which are non-surrogate or should not be escaped (1 second, 877 milliseconds)
[info] - should write string with chars that should be escaped (4 seconds, 88 milliseconds)
[info] - should write string with escaped Unicode chars when it is specified by provided writer config (1 second, 842 milliseconds)
[info] - should throw i/o exception in case of surrogate pair character (19 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for byte
[info] - should write any short values (421 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for short
[info] - should write any short values (4 seconds, 374 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for int
[info] - should write any int values (3 seconds, 298 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for long
[info] - should write any long values (5 seconds, 258 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for float
[info] - should write finite float values (9 seconds, 645 milliseconds)
[info] - should write float values exactly as expected (2 milliseconds)
[info] - should write round-even float values (1 millisecond)
[info] - should throw i/o exception on non-finite numbers (41 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for double
[info] - should write finite double values (11 seconds, 1 milliseconds)
[info] - should write double values exactly as expected (2 milliseconds)
[info] - should write round-even double values (2 milliseconds)
[info] - should throw i/o exception on non-finite numbers (25 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for BigInt
[info] - should don't write null value (3 milliseconds)
[info] - should write number values (37 seconds, 230 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for BigDecimal
[info] - should don't write null value (3 milliseconds)
[info] - should write number values (28 seconds, 151 milliseconds)
[info] JsonWriter.writeBase16Val
[info] - should don't write null value (2 milliseconds)
[info] - should write bytes as Base16 string according to format that defined in RFC4648 (11 seconds, 61 milliseconds)
[info] JsonWriter.writeBase64Val and JsonWriter.writeBase64UrlVal
[info] - should don't write null value (5 milliseconds)
[info] - should write bytes as Base64 string according to format that defined in RFC4648 (10 seconds, 98 milliseconds)
[info] JsonWriter.writeRawVal
[info] - should don't write null value (1 millisecond)
[info] - should write raw bytes as is (4 seconds, 765 milliseconds)
[info] JsonWriter.writeNull
[info] - should write null value (1 millisecond)
[info] JsonWriter.writeArrayStart and JsonWriter.writeArrayEnd
[info] - should allow to write an empty JSON array (1 millisecond)
[info] - should allow to write a compact JSON array with values separated by comma (2 milliseconds)
[info] - should allow to write a prettified JSON array with values separated by comma (2 milliseconds)
[info] JsonWriter.writeObjectStart and JsonWriter.writeObjectEnd
[info] - should allow to write an empty JSON object (1 millisecond)
[info] - should allow to write a compact JSON array with key/value pairs separated by comma (2 milliseconds)
[info] - should allow to write a prettified JSON array with key/value pairs separated by comma (2 milliseconds)
[info] ScalaTest
[info] Run completed in 5 minutes, 38 seconds.
[info] Total number of tests run: 77
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 77, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[info] Passed: Total 77, Failed 0, Errors 0, Passed 77
[success] Total time: 344 s (05:44), completed May 12, 2020 7:24:06 PM
andriy@notebook:~/Projects/com/github/plokhotnyuk/jsoniter-scala$ export PATH=/usr/lib/jvm/graalvm-ee-java8/jre/languages/js/bin:$PATH
andriy@notebook:~/Projects/com/github/plokhotnyuk/jsoniter-scala$ sbt 'jsoniter-scala-coreJS/testOnly *JsonWriterSpec'
[info] Loading global plugins from /home/andriy/.sbt/1.0/plugins
[info] Loading settings for project jsoniter-scala-build from plugins.sbt ...
[info] Loading project definition from /home/andriy/Projects/com/github/plokhotnyuk/jsoniter-scala/project
[info] Loading settings for project jsoniter-scala from release.sbt,build.sbt,version.sbt ...
[info] Set current project to jsoniter-scala (in build file:/home/andriy/Projects/com/github/plokhotnyuk/jsoniter-scala/)
[info] JsonWriterSpec:
[info] WriterConfig.<init>
[info] - should have handy defaults (3 milliseconds)
[info] - should throw exception in case for unsupported values of params (4 milliseconds)
[info] JsonWriter.isNonEscapedAscii
[info] - should return false for all escaped ASCII or non-ASCII chars (3 seconds, 382 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and and JsonWriter.writeKey for boolean
[info] - should write valid true and false values (6 milliseconds)
[info] JsonWriter.writeNonEscapedAsciiVal and JsonWriter.writeNonEscapedAsciiKey
[info] - should don't write null value (3 milliseconds)
[info] - should write string of Ascii chars which should not be escaped (8 seconds, 77 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for UUID
[info] - should don't write null value (3 milliseconds)
[info] - should write UUID as a string representation according to format that defined in IETF RFC4122 (section 3) (4 seconds, 338 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for Duration
[info] - should don't write null value (3 milliseconds)
[info] - should write Duration as a string representation according to ISO-8601 format (4 seconds, 206 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for Instant
[info] - should don't write null value (4 milliseconds)
[info] - should write Instant as a string representation according to ISO-8601 format (6 seconds, 49 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for LocalDate
[info] - should don't write null value (3 milliseconds)
[info] - should write LocalDate as a string representation according to ISO-8601 format (2 seconds, 925 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for LocalDateTime
[info] - should don't write null value (3 milliseconds)
[info] - should write LocalDateTime as a string representation according to ISO-8601 format (2 seconds, 796 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for LocalTime
[info] - should don't write null value (3 milliseconds)
[info] - should write LocalTime as a string representation according to ISO-8601 format (877 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for MonthDay
[info] - should don't write null value (2 milliseconds)
[info] - should write MonthDay as a string representation according to ISO-8601 format (1 second, 312 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for OffsetDateTime
[info] - should don't write null value (2 milliseconds)
[info] - should write OffsetDateTime as a string representation according to ISO-8601 format (2 seconds, 75 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for OffsetTime
[info] - should don't write null value (3 milliseconds)
[info] - should write OffsetTime as a string representation according to ISO-8601 format (1 second, 376 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for Period
[info] - should don't write null value (2 milliseconds)
[info] - should write Period as a string representation according to ISO-8601 format (2 seconds, 72 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for Year
[info] - should don't write null value (3 milliseconds)
[info] - should write Year as a string representation according to ISO-8601 format (1 second, 831 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for YearMonth
[info] - should don't write null value (2 milliseconds)
[info] - should write YearMonth as a string representation according to ISO-8601 format (1 second, 134 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for ZonedDateTime
[info] - should don't write null value (3 milliseconds)
[info] - should write ZonedDateTime as a string representation according to ISO-8601 format with optional IANA timezone identifier in JDK 8+ format (8 seconds, 435 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for ZoneOffset
[info] - should don't write null value (403 milliseconds)
[info] - should write ZoneOffset as a string representation according to ISO-8601 format (942 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for ZoneId
[info] - should don't write null value (2 milliseconds)
[info] - should write ZoneId as a string representation according to ISO-8601 format for timezone offset or JDK 8+ format for IANA timezone identifier (1 second, 510 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for string
[info] - should don't write null value (2 milliseconds)
[info] - should write string of Unicode chars which are non-surrogate and should not be escaped (6 seconds, 524 milliseconds)
[info] - should write strings with chars that should be escaped (8 seconds, 116 milliseconds)
[info] - should write strings with escaped Unicode chars when it is specified by provided writer config (6 seconds, 16 milliseconds)
[info] - should write strings with valid character surrogate pair (2 seconds, 85 milliseconds)
[info] - should write string with mixed Latin-1 characters when escaping of Unicode chars is turned on (1 millisecond)
[info] - should write string with mixed UTF-8 characters when escaping of Unicode chars is turned off (0 milliseconds)
[info] - should throw i/o exception in case of illegal character surrogate pair (49 seconds, 294 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeKey for char
[info] - should write string with Unicode chars which are non-surrogate or should not be escaped (1 second, 78 milliseconds)
[info] - should write string with chars that should be escaped (2 seconds, 732 milliseconds)
[info] - should write string with escaped Unicode chars when it is specified by provided writer config (747 milliseconds)
[info] - should throw i/o exception in case of surrogate pair character (20 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for byte
[info] - should write any short values (726 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for short
[info] - should write any short values (1 second, 962 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for int
[info] - should write any int values (1 second, 315 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for long
[info] - should write any long values (2 seconds, 920 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for float
[info] - should write finite float values (6 seconds, 399 milliseconds)
[info] - should write float values exactly as expected (3 milliseconds)
[info] - should write round-even float values (2 milliseconds)
[info] - should throw i/o exception on non-finite numbers (29 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for double
[info] - should write finite double values (7 seconds, 461 milliseconds)
[info] - should write double values exactly as expected (3 milliseconds)
[info] - should write round-even double values (2 milliseconds)
[info] - should throw i/o exception on non-finite numbers (26 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for BigInt
[info] - should don't write null value (3 milliseconds)
[info] - should write number values (18 seconds, 475 milliseconds)
[info] JsonWriter.writeVal and JsonWriter.writeValAsString and JsonWriter.writeKey for BigDecimal
[info] - should don't write null value (3 milliseconds)
[info] - should write number values (17 seconds, 368 milliseconds)
[info] JsonWriter.writeBase16Val
[info] - should don't write null value (2 milliseconds)
[info] - should write bytes as Base16 string according to format that defined in RFC4648 (7 seconds, 68 milliseconds)
[info] JsonWriter.writeBase64Val and JsonWriter.writeBase64UrlVal
[info] - should don't write null value (4 milliseconds)
[info] - should write bytes as Base64 string according to format that defined in RFC4648 (5 seconds, 341 milliseconds)
[info] JsonWriter.writeRawVal
[info] - should don't write null value (2 milliseconds)
[info] - should write raw bytes as is (2 seconds, 986 milliseconds)
[info] JsonWriter.writeNull
[info] - should write null value (1 millisecond)
[info] JsonWriter.writeArrayStart and JsonWriter.writeArrayEnd
[info] - should allow to write an empty JSON array (0 milliseconds)
[info] - should allow to write a compact JSON array with values separated by comma (8 milliseconds)
[info] - should allow to write a prettified JSON array with values separated by comma (1 millisecond)
[info] JsonWriter.writeObjectStart and JsonWriter.writeObjectEnd
[info] - should allow to write an empty JSON object (1 millisecond)
[info] - should allow to write a compact JSON array with key/value pairs separated by comma (2 milliseconds)
[info] - should allow to write a prettified JSON array with key/value pairs separated by comma (1 millisecond)
[info] ScalaTest
[info] Run completed in 3 minutes, 23 seconds.
[info] Total number of tests run: 77
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 77, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[info] Passed: Total 77, Failed 0, Errors 0, Passed 77
[success] Total time: 208 s (03:28), completed May 12, 2020 7:37:09 PM

javascript

Most helpful comment

I don't know if this is the same issue or not, but the fact that Graal puts it's own node and npm executable in $JAVA_HOME/bin is incredibly detrimental. Just because someone wants to use a different JVM, doesn't mean they want to replace Node, (especially with a much, much slower version).

All 3 comments

Some benchmarks show more than 100x slowdown with GraalVM CE (reported scores and errors bellow are in microsecond per operation):

andriy@notebook:~/Projects/com/github/sjrd/scalajs-benchmarks/json/.js/target/scala-2.12$ /usr/bin/node json-opt.js
AvSystemGenCodecReading;json.Json$$anon$109: Node.js;457.7710198607037;1.7519982898784237
AvSystemGenCodecWriting;json.Json$$anon$110: Node.js;419.58568541463274;0.7920684717966959
BorerReading;json.Json$$anon$111: Node.js;143.1768958398397;0.32687052818421675
BorerWriting;json.Json$$anon$112: Node.js;267.9409419149654;0.5096159412807705
CirceWriting;json.Json$$anon$113: Node.js;529.5426255872051;1.4471623215733558
JsoniterScalaReading;json.Json$$anon$114: Node.js;117.5137380398908;0.203123680884847
JsoniterScalaWriting;json.Json$$anon$115: Node.js;156.9742956483412;0.2087148477221151
uPickleReading;json.Json$$anon$116: Node.js;527.8570856075772;1.2348012416616183
uPickleScalaWriting;json.Json$$anon$117: Node.js;463.5305040527048;1.3981290532634494
andriy@notebook:~/Projects/com/github/sjrd/scalajs-benchmarks/json/.js/target/scala-2.12$ /usr/lib/jvm/graalvm-ce-java8/jre/languages/js/bin/node json-opt.js
AvSystemGenCodecReading;json.Json$$anon$109: Node.js;3663.1774207977064;336.086597215144
AvSystemGenCodecWriting;json.Json$$anon$110: Node.js;62907.03379168796;4748.787626344525
BorerReading;json.Json$$anon$111: Node.js;45052.532514338105;4283.314231349664
BorerWriting;json.Json$$anon$112: Node.js;2054.647194253576;208.04945841752578
CirceWriting;json.Json$$anon$113: Node.js;60676.41663976014;6195.672231806127
JsoniterScalaReading;json.Json$$anon$114: Node.js;19736.883888290704;2079.924722628596
JsoniterScalaWriting;json.Json$$anon$115: Node.js;16776.531140456038;1524.9671080622613
uPickleReading;json.Json$$anon$116: Node.js;36638.617853611344;4008.820949217976
uPickleScalaWriting;json.Json$$anon$117: Node.js;8194.298901610442;1045.027449179559
andriy@notebook:~/Projects/com/github/sjrd/scalajs-benchmarks/json/.js/target/scala-2.12$ /usr/lib/jvm/graalvm-ee-java8/jre/languages/js/bin/node json-opt.js
AvSystemGenCodecReading;json.Json$$anon$109: Node.js;1906.858519823463;215.0509114056345
AvSystemGenCodecWriting;json.Json$$anon$110: Node.js;1742.0686705599564;200.4327233048322
BorerReading;json.Json$$anon$111: Node.js;2927.72190915539;366.8360265708109
BorerWriting;json.Json$$anon$112: Node.js;719.2395870914721;73.58201439224315
CirceWriting;json.Json$$anon$113: Node.js;4839.0949725719565;479.83758806102
JsoniterScalaReading;json.Json$$anon$114: Node.js;2051.3232465782394;223.31473102756607
JsoniterScalaWriting;json.Json$$anon$115: Node.js;333.44004925185965;38.462003251335524
uPickleReading;json.Json$$anon$116: Node.js;2375.763826190479;274.41514556308806
uPickleScalaWriting;json.Json$$anon$117: Node.js;2923.033415016107;378.2754361789721

Please, try the attached script to reproduce: json-opt.zip

Hi @plokhotnyuk

thanks for reporting this, especially for bringing it in an easily executable format for us!

Our performance is not great on this, confirmed. The reason is that this is to a large extent measuring warm-up performance, i.e. the speed of our compiler. This example executes 1.6 MB of Javascript source code for ~35 seconds total. At this point, only a part of the relevant source has been compiled by GraalVM. The problem is probably worsened by the fact that 9 different parts seem to be executed and measured - which makes each part smaller, but constitutes a state shift every few seconds (I have not yet analyzed how much of the code is shared between the 9 individual measure units).

I'll have a look at the compiler graphs and see if there is any pattern obvious that might help us compile this faster in the future. We are trying to improve performance for such cases as well, but our typical performance goal is longer-running applications.

Best,
Christian

I don't know if this is the same issue or not, but the fact that Graal puts it's own node and npm executable in $JAVA_HOME/bin is incredibly detrimental. Just because someone wants to use a different JVM, doesn't mean they want to replace Node, (especially with a much, much slower version).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

helloguo picture helloguo  路  3Comments

helloguo picture helloguo  路  3Comments

ghost picture ghost  路  3Comments

jinwuxia picture jinwuxia  路  3Comments

sdeleuze picture sdeleuze  路  3Comments