jsoniter scala

2025-12-11 0 366

JSONITER-SCALA

Scala宏,用于编译时间生成安全和超快速的JSON编解码器。

JSONITER-SCALA解析和序列化性能与:Borer,Circe,Circe与Jsoniter-Scala Booster,Jackson-Module-Scala,JSON4S-JACKSON,JSON4S-NATICE,JSON4S-NATICE,PLAY-JSON,PLAY-JSON,PLAY-JSON,JON-UPSCALA BOOSTER,SMITHYY4SING4SING4SYSY4SING4SYSY JOSY, Weepickle,Zio-Json,Zio-Schema-json库在以下环境中使用不同的JDK和GRAALVM版本:Intel®Core™Ultra 9 285K CPU @ 3.7GHz(Max 5.7GHz,200S BOOST),RAM 64GB DDR5-6400,UBUNTU 25.04(LINUX 6.14)(JUN-6.14)(linux 6.14),以及最新的21/21/21/21/21/21/21/21/21/21/及以来GRAALVM社区JDK 17/21/25-EA和GRAALVM JDK 17/21/25-EA*。

基准测试对浏览器的最新结果,将Jsoniter-Scala与:Circe,Circe与Jsoniter-Scala Booster,Play-Json,Play-Json,Jsoniter-Scala Booster,Smithy4S-JSON,Smithy4S-JSON,UPICKLE,UPICKLE,ZIO-JSON,ZIO-JSON和ZIO-SCHEMA-JSON和ZIO-SCHEMA-JSON汇编的2015年3月30日,应用于Intel®Core™Ultra 9 285K CPU @ 3.7GHz(最大5.7GHz,200s Boost),RAM 64GB DDR5-6400,在Windows 11 Pro(24H2)上。

内容

  • 致谢
  • 目标
  • 功能和局限性
  • 如何使用
  • 已知问题
  • 如何发展

致谢

该图书馆始于宏,该宏为Java Reader和Writer重新使用JSONITER(JSON-ITERATOR),但随后该图书馆演变为具有自己的解析和序列化的机制核心。

通过Scala Macros生成编解码器和主要细节的想法是从Kryo Macros(最初由Alexander Nemish开发的)借用的,并适应了JSON域的需求。

在Avystem Commons和Magnolia库中窥视了其他Scala宏特征。

java.time.*值是受DSL-JSON实现java.time.OffsetDateTime的启发的。

其他项目和博客文章有助于提供无与伦比的安全性和绩效特征来解析和序列化数字:

  • Schubfach-将双打和浮动序列序列到文本表示的最有效,最简洁的方法
  • 锈蚀 – 完全从文本表示形式中解析并翻倍的最有效方法
  • Big -Math-使用O(n^2) O(n^1.5)复杂性的BigIntBigDecimal值的解析,而不是使用Java的实现,其中n是许多数字
  • 詹姆斯·安哈尔特(James Anhalt

JVM平台的一堆SWAR技术技巧基于以下项目和博客文章:

  • 鲍尔(Borer) – 用8字节单词快速解析JSON字符串
  • SIMDJSON-通过8字节单词对数字的字符串快速检查
  • FastDoubleParser-通过8字节单词的数字快速解析
  • 约翰尼·李(Johnny Lee)的文章 – 快速串到几秒钟的转换

对所有贡献者的敬意:

目标

  1. 安全:通过失败快速的方法和清晰的报告,验证解析值,为次优的数据结构提供可配置的限制,安全默认值可用于DOS攻击,生成编解码器,生成在解析过程中创建固定类的实例以避免RCE攻击的实例
  2. Correctness : support the latest JSON format (RFC-8259), do not replace illegally encoded characters of string values by placeholder characters, parse numbers with limited binary representation doing half even rounding for too long JSON numbers, serialize floats and doubles to the shortest textual representation without loosing of precision
  3. 速度:直接从UTF-8字节到数据结构并返回JSON的解析和序列化,在不使用运行时反射或运行时代码生成的情况下疯狂地进行快速进行操作,中间ASTS,Hash Maps,但使用最少的分配和复制
  4. 生产力:使用一行宏来递归为复杂类型得出编解码器,以编译时间来最大程度地减少运行时问题的可能性,可选地打印生成的源作为编译器输出,以证明安全性和正确性,或者被重复使用,或者作为起点作为定制编码的实现,并立即将其编码为null scodecs,以立即进行编码。
  5. 人体工程学:具有预先配置的最安全和常见用法的默认用途,可以通过编译和运行时的配置实例轻松更改,结合编译时间注释和隐性,包含JSON的文本表示,提供漂亮的打印选项,在错误上提供六角形,以加快错误上下文的视图,以加快错误上下文的视野

功能和局限性

  • json从StringArray[Byte]java.nio.ByteBufferjava.io.InputStream / java.io.FileInputStream中解析
  • json序列化到StringArray[Byte]java.nio.ByteBufferjava.io.OutputStream / java.io.FileOutputStream
  • 通过指定位置和限制来支持从或写作到Array[Byte]java.nio.ByteBuffer的一部分
  • java.io.InputStream / java.io.FileInputStream中解析流json值和JSON阵列,而无需将所有输入和解析值保存在内存中
  • 直接使用缓冲字节时,仅支持UTF-8编码,但是从/到String序列化JSON并序列化JSON(虽然效率较低)
  • 用逃脱的字符解析JSON键和字符串值
  • 可以生成编解码器,用于原始,盒装原始,枚举,弦, StringBigIntBigDecimal ,bigdecimal,bigdecimal, OptionEitherjava.util.UUIDjava.time.*在这里列出
  • 应该使用尚未在非第一个参数列表中定义默认值的主构造函数来定义类
  • 非案例Scala类也支持,但是它们应该为主要构造函数的所有参数都有Getter登录器
  • 作为地图键支持的类型是原始键,盒装原语,枚举, StringBigIntBigDecimaljava.util.UUIDjava.time.*
  • 可以通过隐式make Ordering[K]实例来定制排序地图和集合的编解码器
  • 核心模块支持读取和写入字节数组从/到base16和base64表示(RFC 4648)用于自定义编解码器
  • 对于映射到字节数组,数字和java.time.*类型
  • 支持一阶和更高类型
  • 以密封性状或Scala类作为基本类型和非抽象的Scala类或对象为叶类的2种ADT表示的支持:1st表示使用歧视器字段,并使用字符串类型的值,第二个使用字符串的字符串为对象和包装器JSON对象的字符串值,用于case Class Object for Case Class Object
  • 映射到映射到地图的JSON值和JSON对象键的隐式分解值编解码器,允许注入您的自定义编解码器,以添加其他类型的支持或更改JSON中已支持类的JSON中的表示形式
  • 支持上述所有类型的类型别名
  • 生成的编解码器仅支持类实例的无环图
  • 实例字段的顺序在生成的编解码器的序列化过程中保留
  • 如果在类实例中检测到重复的键,则引发解析例外(除外)
  • 通过投掷NullPointerException错误禁止序列化null
  • 仅适用于可选或收集类型的null值解析(这意味着None值或空收集)以及定义非默认值的字段
  • 构造函数中定义的默认值的字段是可选的,需要其他字段(无需特殊注释)
  • 值等于默认值的值,或者是空的选项/集合/数组未序列化以提供稀疏的输出
  • 任何直接使用的值或作为构造函数参数默认值的一部分的值,都应具有equals方法的正确实现(它主要涉及非案例类或具有自定义编解码器的其他类型)
  • 可以将字段注释为瞬态,也可以在构造函数中定义,以避免解析和序列化
  • 可以在类的主要构造函数中序列化/解析字段名称
  • 通过使用自定义编解码器可以读取和写入任何任意字节或原始值
  • 解析异常总是报告Array[Byte]java.nio.ByteBufferjava.io.InputStream / java.io.FileInputStream的十六进制偏移,发生在其中发生,并受到内部Byte Bufferer Bufferer Interner byte Bufferer的误差部分影响
  • 可通过字段注释能力配置的能力从/到字符串值读取数字字段
  • 密钥和价值编解码器都专门使用原始图,而无需拳击/拆箱
  • java.io.InputStream / java.io.FileInputStream或序列化java.io.OutputStream / java.io.FileOuputStream时,无需额外缓冲
  • 仅将黑匣子宏仅用于编解码器生成可确保您的类型永远不会更改
  • 订购生成的代码以保留校验和最大化远程构建工具的命中率
  • 能够使用编解码器范围的CodecMakerConfig.PrintCodec类型打印编解码器生成的代码
  • 不包括Scala的scala-library (所有平台)和scala-java-time (替换JDKS java.time._类型scala.js和Scala本地),对运行时的额外库无依赖关系
  • 在Scala.js和Scala本机平台上,如果您需要对UTC以外的时区的支持
  • 编解码器和运行时配置实现java.io.Serializable可在分布式计算中更容易使用
  • 支持对另一个软件包的阴影支持特定发布版本
  • 补丁版本是向后和向前兼容的,次要版本是向后兼容的
  • 与CIRCE集成,以更快地解析/序列化和解码/编码到/从CIRCE AST
  • 为不同的Scala版本发布:2.12、2.13和3.3
  • JVM的Java 11+版本的支持
  • 支持GRAALVM对本地图像的汇编
  • 对所有受支持的Scala版本的Scala.js 1.0+的支持
  • 支持Scala Native 0.5+的所有受支持的Scala版本
  • 抑制对Scala 2.12和2.13发出的所有编解码器的所有Wartremover警告

可以在编译时设置可配置的选项:

  • 能够从/到字符串值读取/写数字
  • 能够读/写地图作为JSON数组
  • 跳过意外领域或投掷解析例外
  • 跳过具有空收集值的字段的序列化可以关闭以迫使它们的序列化
  • 跳过具有空的可选值的字段的序列化可以关闭以迫使它们的序列化
  • 跳过序列化的序列化值与主构造函数中定义的默认值匹配的字段可以关闭该值的序列化
  • 在JSON输入中需要收集字段的能力
  • 能够在JSON输入中需要具有默认值的字段
  • 能够使用编译时间注释覆盖ADT和字段类的名称
  • 从类及其字段的名称映射函数到JSON键,或将Java枚举值的名称映射到JSON字符串和背部的函数,包括在生成编解码器中所有字段的实施蛇case,kebab-case,camelcase,camelcase或pascalcase name的预定义函数
  • ADT的鉴别器字段的可选名称
  • 用于区分ADT类的歧视器字段值的映射函数
  • 解析BigDecimal值时,能够设置精度,比例限制和最大数字数量
  • 解析BigInt值时,可以设置最大数字数量的能力
  • 解析位集时设置最大允许值
  • 解析或地图时设置插入数量的限制
  • 可以关闭递归数据结构的汇编错误
  • 当歧视器不是第一个字段时,投掷运行时错误可以关闭
  • 能够从/到ID编号解析/序列化Scala枚举的能力
  • 能够得出可以区分null字段值的编解码器,而丢失字段则是Some(None) ,而None Option[Option[_]]
  • 能够打开ADT中Scala对象的类似CIRCE的编码
  • 能够禁用生成用于解码或编码的实施
  • 需要定义默认值的字段
  • 不需要检查字段重复时,能够生成较小,更高效的编解码器
  • 能够嵌入非价值类的能力,而非价值类只有一个参数

在运行时更改解析和序列化的选项列表:

  • 具有逃逸的Unicode字符的字符串序列化为ASCII兼容
  • 产出及其步骤的缩进
  • 默认情况下,投掷无堆栈的解析例外,以大大降低对性能的影响,而堆栈痕迹可以开发进行调试
  • 关闭受内部字节缓冲区误差部分影响的十六进制倾倒,以降低对性能的影响
  • 可以根据更大或较小的16字节线调整十六进制的尺寸
  • java.io.InputStreamjava.nio.DirectByteBuffer解析时,内部输入缓冲区的最大大小
  • java.io.InputStreamjava.nio.DirectByteBuffer解析时,内部输入缓冲区的首选大小
  • 序列化至java.io.OutputStreamjava.nio.DirectByteBuffer时,内部输出缓冲区的首选尺寸
  • 解析字符串值时炭缓冲区的最大大小
  • 解析字符串值时首选的炭缓冲区大小

v2.13.5.2版本是支持JDK 8+和本机映像汇编的最后一个版本,该版本具有较早版本的GRAALVM。

v2.13.3.2版本是支持Scala 2.11的最后一个版本。

v2.30.2版本是支持Scala本机0.4+的最后一个版本。

有关即将到来的功能和修复,请参阅提交和问题页面。

如何使用

假设您有以下数据结构:

 case class Device ( id : Int , model : String )

case class User ( name : String , devices : Seq [ Device ])

将核心库带有“编译”范围和带有“编译内部”或“提供”范围的宏库中的SBT依赖列表:

libraryDependencies ++= Seq (
  // Use the %%% operator instead of %% for Scala.js and Scala Native 
  \" com.github.plokhotnyuk.jsoniter-scala \" %% \" jsoniter-scala-core \" % \" 2.37.0 \" ,
  // Use the \"provided\" scope instead when the \"compile-internal\" scope is not supported  
  \" com.github.plokhotnyuk.jsoniter-scala \" %% \" jsoniter-scala-macros \" % \" 2.37.0 \" % \" compile-internal \"
)

在Scala Cli脚本的开头,使用“ DEP”范围作为核心库或compileonly.dep。

 //> using dep \" com.github.plokhotnyuk.jsoniter-scala::jsoniter-scala-core::2.37.0 \"
//> using compileOnly . dep \" com.github.plokhotnyuk.jsoniter-scala::jsoniter-scala-macros::2.37.0 \"

为需要解析或序列化的顶级类型提供编解码器:

 import com . github . plokhotnyuk . jsoniter_scala . macros . _
import com . github . plokhotnyuk . jsoniter_scala . core . _

given userCodec : JsonValueCodec [ User ] = JsonCodecMaker .make

就是这样!您已经生成了com.github.plokhotnyuk.jsoniter_scala.core.JsonValueCodec的实例,用于整个嵌套数据结构。如果您不打算隔离/将它们从/到JSON序列化(不是User的一部分),则无需为Device等内嵌套类(例如设备)提供中间编解码器,并且使用默认的或相同的派生配置对其编解码器。

现在将其用于从/到String的解析和序列化:

 val user = readFromString[ User ]( \"\"\" {\"name\":\"John\",\"devices\":[{\"id\":1,\"model\":\"HTC One X\"}]} \"\"\" )
val json = writeToString( User ( \" John \" , Seq ( Device ( 2 , \" iPhone X \" ))))

当您的输入来自网络或磁盘时,更有效的方法是解析和序列化:

  • 使用readFromArray / writeToArray字节阵列
  • 使用readFromSubArray / writeToSubArray的字节子阵列
  • java.nio.ByteBuffer实例使用readFromByteBuffer / writeToByteBuffer
  • java.io.InputStream / java.io.OutputStream实例使用readFromStream / writeToStream

此外,从字节解析将检查UTF-8编码并在畸形字节时丢弃错误。

要打印编解码器生成的代码,在make电话之前,将以下行添加到编解码器推导的范围中。

 given CodecMakerConfig . PrintCodec with {}

有关JSONITER-SCALA的更多用例,请查看测试:

  • jsoncodecmakerspec
  • packagespec
  • JSONREDERSPEC
  • JSONWRITERSPEC

所有Scala 3仅通过此目录中的规格测试。

 NOTE: Until official docs will be published, please, use all these tests as tutorials and how-tos to help in your 
journey to become happy users. Also, they are recommended to skim through for checking of your expectation before
selection of this library among others.

您可以使用以下在线服务从JSON示例中生成数据结构的初始版本:

  • JSON2CASECLASS
  • JSON至scala-Case级
  • JSON2Classes
  • QuickType

另外,如果您拥有JSON模式,则以下在线服务可以为您生成相应的数据结构:

  • JSON-SCHEMA-CASE级
  • QuickType

以下库可以为您的现有数据结构生成JSON模式:

与不同的Web框架和HTTP服务器集成的样本:

  • akka-http
  • 火焰
  • 巨人
  • http4s
  • Pekko-HTTP
  • 玩(与Netty Native Transport一起玩)
  • Zio-HTTP

JSONITER-SCALA在OSS库中的使用:

  • akka-http-json-将Scala中一些最好的JSON LIB与Akka HTTP整合在一起
  • Bootzooka-一个项目,可以快速开始开发基于Scala的微服务或Web应用程序,而无需写登录,用户注册等。
  • Caliban-纯粹的功能库,用于构建GraphQl服务器和Scala中的客户端
  • Dijon-使用安全有效的AST表示支持对无模式的JSON的支持
  • Geo -Scala- Geojson的核心AST和实用程序(RFC 7946)等等
  • 铁 – Scala 3中用于精制类型的轻巧库
  • JSONITER-SCALA-CIRCE- CIRCE助推器,用于更快的解析/序列化到/形式circe ast ast and dexoding/decoding/docoding java.time._BigInt类型
  • kafka-serde-scala-隐式将Typeclass编码器转换为Kafka Serialializer,Deserializer,Serde
  • logging4s- scala 3的结构性日志
  • Neotype- Scala 3
  • 宣誓 – 另一个scala -jwt库,其目的是增强用户体验
  • PEKKO-HTTP-JSON-将Scala中一些最好的JSON LIB与Pekko HTTP集成
  • play-json-jsoniter-提供了将play.api.libs.json.JsValue实例转换为字节数组(或字节缓冲区或输出流)的最快方法
  • Scalatest -JSON-具有适当平等和描述性错误消息的Scalatest匹配器
  • Smithy4S -JSON- SCALA的史密斯工具协议
  • STTP-您一直想要的Scala HTTP客户端!
  • STTP -OAUTH2 -OAUTH2客户库在Scala中使用STTP实现
  • Tapir-键入API说明

另外,对于其他OSS项目中的Dependents

对于所有依赖项目,建议使用SBT-Updates插件或Scala管家服务以跟上最新版本的使用。

已知问题

  1. 解析过程中JSON表示的长度没有验证。

如果您的系统可以接受过长的不信任输入,请在使用readFromStream或其他read...调用之前检查输入长度。

另外,如果您的输入是一个值或白空间单独的值,则考虑通过scanJsonArrayFromInputStreamscanJsonValuesFromInputStream而不是readFromStream对其进行解析。

  1. make Macro的配置参数以编译时间评估。它不需要对使用宏调用结果的其他代码的依赖,否则将报告以下汇编错误:
 [error] Cannot evaluate a parameter of the \'make\' macro call for type \'full.name.of.YourType\'. It should not depend on
        code from the same compilation module where the \'make\' macro is called. Use a separated submodule of the project
        to compile all such dependencies before their usage for generation of codecs.

有时,Scala 2编译器可能无法编译make Macro调用,并带有相同的错误消息,用于配置,该配置尚未明确依赖于其他代码。在这些情况下

  • 使用makemake...无参数的宏通话
  • 像在此pr中一样,将make宏调用隔离在分离的对象中
  • 将jsoniter-scala导入到本地,例如这里和这里
  • 使用sbt clean compile stagesbt clean test stage ,而不仅仅是sbt clean stage
  • 如果在Intellij Idea中使用Mill的本机BSP支持,请使用mill clean
  • 确保只有一个版本的Jsoniter-Scala在classPath上!具有不同的版本(例如,通过依赖关系)会触发此错误。使用dependencyTree / dependencyGraph或类似的机制来查看是否是这种情况。如果发生这种情况,请使用DuberRules摆脱错误的版本。
  1. 如果在ADT定义的编译或其派生的编解码器中,可能会发生意外的编译器错误,如果它们嵌套在此处的某些类或功能中。

两种情况下的解决方法都是相同的:不要将ADT定义封闭到外部性状函数中,而是使用外对象(而不是类)。

  1. Scala 3中的make电话的编译时间配置对名称映射的可能表达式有限。

请使用单位测试中的CodecMakerConfig使用示例。

  1. 当重复使用JsonReaderJsonWriter的同一实例时,嵌套解析或序列化例程可能发生意外解析或序列化错误:
scanJsonValuesFromStream[ String ](in) { s =>
  readFromString[ String ](s)
}

除了最嵌套的呼叫以外,解决方法正在使用重新入学解析或序列化例程。这将在每个重新输入呼叫上创建JsonReaderJsonWriter的新实例:

scanJsonValuesFromStreamReentrant[ String ](in) { s =>
  readFromString[ String ](s)
}
  1. scala.js不支持从Java源编译的Java枚举,因此将失败与以下错误链接到以下错误:
 [error] Referring to non-existent class com.github.plokhotnyuk.jsoniter_scala.macros.Level
[error]   called from private com.github.plokhotnyuk.jsoniter_scala.macros.JsonCodecMakerSpec.$anonfun$new$24()void
[error]   called from private com.github.plokhotnyuk.jsoniter_scala.macros.JsonCodecMakerSpec.$anonfun$new$1()void
[error]   called from constructor com.github.plokhotnyuk.jsoniter_scala.macros.JsonCodecMakerSpec.<init>()void
[error]   called from static constructor com.github.plokhotnyuk.jsoniter_scala.macros.JsonCodecMakerSpec.<clinit>()void
[error]   called from core module analyzer

Scala 2的解决方法是将JVM和其他平台的源拆分源,并为Scala.js和Scala Native使用Java Enum Myulation。

JVM的代码:

 public enum Level {
    HIGH , LOW ;
}

Scala.js和Scala本地的代码:

 object Level {
  val HIGH : Level = new Level ( \" HIGH \" , 0 )
  val LOW : Level = new Level ( \" LOW \" , 1 )
  
  val values : Array [ Level ] = Array ( HIGH , LOW )

  def valueOf ( name : String ) : Level =
    if ( HIGH .name() == name) HIGH
    else if ( LOW .name() == name) LOW
    else throw new IllegalArgumentException ( s \" Unrecognized Level name: $name \" )
}

final class Level private ( name : String , ordinal : Int ) extends Enum [ Level ](name, ordinal)

对于Scala 3,对于所有平台,解决方法都相同:

 enum Level extends Enum [ Level ] {
  case HIGH
  case LOW
}
  1. Scala 3编译器无法为具有具体类型参数的通用类型提供匿名编解码器:
 case class DeResult [ T ]( isSucceed : Boolean , data : T , message : String )

case class RootPathFiles ( files : List [ String ])

given JsonValueCodec [ DeResult [ Option [ String ]]] = JsonCodecMaker .make
given JsonValueCodec [ DeResult [ RootPathFiles ]] = JsonCodecMaker .make

当前3.2.x版本的Scalac版本失败,重复定义错误如下:

 [error] 19 |      given JsonValueCodec[DeResult[RootPathFiles]] = JsonCodecMaker.make
[error]    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[error]    |given_JsonValueCodec_DeResult is already defined as given instance given_JsonValueCodec_DeResult

解决方法正在使用编解码器的命名实例:

 given codecOfDeResult1 : JsonValueCodec [ DeResult [ Option [ String ]]] = JsonCodecMaker .make
given codecOfDeResult2 : JsonValueCodec [ DeResult [ RootPathFiles ]] = JsonCodecMaker .make

或私人类型的别名,具有某些特征given定义给定定义:

 trait DeResultCodecs :

  private type DeResult1 = DeResult [ Option [ String ]]
  private type DeResult2 = DeResult [ RootPathFiles ]

  given JsonValueCodec [ DeResult1 ] = JsonCodecMaker .make
  given JsonValueCodec [ DeResult2 ] = JsonCodecMaker .make

end DeResultCodecs

object DeResultCodecs extends DeResultCodecs

import DeResultCodecs . given
  1. 当前, JsonCodecMaker.make CALL无法为Scala 3不透明和工会类型提供编解码器。解决方法是针对JsonCodecMaker.make之前用implicit val定义的这些类型的自定义编解码器。呼叫,就像这里和这里一样。

  2. 如果ADT LEAF类/对象包含其简单名称中的点,则默认名称映射器将剥离名称到最后一个点字符。解决方法是在这里使用@named注释:

 sealed abstract class Version ( val value : String )

object Version {
  @ named( \" 8.10 \" ) case object `8.10` extends Version ( \" 8.10 \" )

  @ named( \" 8.09 \" ) case object `8.09` extends Version ( \" 8.9 \" )
}
  1. 当将JSON字符串解析为数字或java.time.*不支持ASCII字符编码的值。解决方法是使用自定义编解码器,将这些值解析为字符串,然后将它们转换为相应的类型,如以下方式:
 implicit val customCodecOfOffsetDateTime : JsonValueCodec [ OffsetDateTime ] = new JsonValueCodec [ OffsetDateTime ] {
  private [ this ] val defaultCodec : JsonValueCodec [ OffsetDateTime ] = JsonCodecMaker .make[ OffsetDateTime ]
  private [ this ] val maxLen = 44 // should be enough for the longest offset date time value
  private [ this ] val pool = new ThreadLocal [ Array [ Byte ]] {
    override def initialValue () : Array [ Byte ] = new Array [ Byte ](maxLen + 2 )
  }

  def nullValue : OffsetDateTime = null

  def decodeValue ( in : JsonReader , default : OffsetDateTime ) : OffsetDateTime = {
    val buf = pool.get
    val s = in.readString( null )
    val len = s.length
    if (len <= maxLen && {
      buf( 0 ) = \'\"\'
      var bits, i = 0
      while (i < len) {
        val ch = s.charAt(i)
        buf(i + 1 ) = ch.toByte
        bits |= ch
        i += 1
      }
      buf(i + 1 ) = \'\"\'
      bits < 0x80
    }) {
      try {
        return readFromSubArrayReentrant(buf, 0 , len + 2 , ReaderConfig )(defaultCodec)
      } catch {
        case NonFatal (_) => ()
      }
    }
    in.decodeError( \" illegal offset date time \" )
  }

  def encodeValue ( x : OffsetDateTime , out : JsonWriter ) : Unit = out.writeVal(x)
}
  1. 请勿使用implicit definline given方法来生成自定义代码。 Scala 3.5.0+显示了编译时间警告新的匿名类定义,每个内联站点将在某些inline given案例New anonymous class definition will be duplicated at each inline site ,但是对于其他用例,编译器将默默生成重复的编解码器实例。为了减轻该编解码器生成方法的转换为def并明确推导自定义编解码器,如下所示:
 object Tags {
  opaque type Tagged [ + V , + T ] = Any

  type @@ [ + V , + T ] = V & Tagged [ V , T ]

  def tag [ T ] : [ V ] => V => V @@ Tag = [ V ] => ( v : V ) => v
}

object Graph {
  import Tags .{ @@ , tag }

  def tagJsonValueCodec [ V , T ]( codec : JsonValueCodec [ V ]) : JsonValueCodec [ V @@ T ] = new JsonValueCodec [ V @@ T ] :
    // println(\"+1\")
    override def decodeValue ( in : JsonReader , default : V @@ T ) : V @@ T = tag[ T ](codec.decodeValue(in, default : V ))
    override def encodeValue ( x : V @@ T , out : JsonWriter ) : Unit = codec.encodeValue(x, out)
    override def nullValue : V @@ T = tag[ T ](codec.nullValue)

  trait NodeIdTag

  type NodeId = Int @@ NodeIdTag

  case class Node ( id : NodeId , name : String )
  case class Edge ( node1 : NodeId , node2 : NodeId )

  given JsonValueCodec [ Graph . NodeId ] = Graph .tagJsonValueCodec( JsonCodecMaker .make)
  given JsonValueCodec [ Graph . Node ] = JsonCodecMaker .make
  given JsonValueCodec [ Graph . Edge ] = JsonCodecMaker .make
}

如何发展

随时在聊天,开放问题中提出问题,或通过创建拉动请求(对文档,代码和测试的改进得到高度赞赏)。

当前, gh-pages分支包含许多基准结果的历史记录数据,因此为避免使用10GB的10GB使用--single-branch分支选项仅获取源。

如果在叉子上开发,请确保下载git标签(SBT构建要求):

git remote add upstream git@github.com:plokhotnyuk/jsoniter-scala.git
git fetch --tags upstream

构建scala.js和scala天然模块的先决条件是clang 18.x and node.js 16.x.以下命令顺序对我有用:

sudo apt install clang libstdc++-12-dev libgc-dev 
curl https://raw.githu*buser**content.com/creationix/nvm/master/install.sh | bash 
source ~ /.bashrc
nvm install 16
node -v

获取可用依赖性更新的报告

sbt \" ;dependencyUpdates; reload plugins; dependencyUpdates; reload return \"

运行测试,检查覆盖范围和二进制兼容性

sbt -java-home /usr/lib/jvm/jdk-11 ++2.13.16 clean coverage jsoniter-scala-coreJVM/test jsoniter-scala-circeJVM/test jsoniter-scala-macrosJVM/test jsoniter-scala-benchmarkJVM/test coverageReport
sbt -java-home /usr/lib/jvm/jdk-11 clean +test +mimaReportBinaryIssues

当心:Scala 2和Scala Scala 3的Scala Scala社区构建中包含JSONITER-SCALA。

运行JVM基准

在基准运行之前,请检查您的CPU是否在performance模式下工作(不是powersave One)。在Linux上使用以下命令以打印电流并设置performance模式:

cat /sys/devices/system/cpu/cpu * /cpufreq/scaling_governor
for i in $( ls /sys/devices/system/cpu/cpu * /cpufreq/scaling_governor ) ; do echo performance | sudo tee $i ; done

然后使用以下方式查看您的CPU频率

cat /proc/cpuinfo | grep -i mhz

停止不需要的申请和服务。运行服务列表可以通过:

sudo service --status-all | grep \' \\[ + \\] \'
sudo systemctl list-units --state running

然后清除缓存内存以提高系统性能。在不必重新启动系统的情况下清除Linux上清除缓存内存的一种方法:

sudo su
free -m -h && sync && echo 3 > /proc/sys/vm/drop_caches && free -m -h

JMH工具的SBT插件用于基准测试,以查看其所有功能和选项,请检查SBT-JMH文档和JMH工具文档

了解如何在AlekseyShipilёV和Nitsan Wakart的博客中发布的JMH样品和JMH文章中编写基准测试。

可用选项的列表可以通过:

sbt jsoniter-scala-benchmarkJVM/clean \' jsoniter-scala-benchmarkJVM/Jmh/run -h \'

基准的结果可以以不同的格式存储: *.csv, *.json等。所有支持的格式都可以列出:

sbt jsoniter-scala-benchmarkJVM/clean \' jsoniter-scala-benchmarkJVM/Jmh/run -lrf \'

JMH允许使用不同的参考器运行基准测试,可以获取支持使用的列表(可能需要输入用户密码):

sbt jsoniter-scala-benchmarkJVM/clean \' jsoniter-scala-benchmarkJVM/Jmh/run -lprof \'

可以通过以下命令打印profiler选项的帮助( <profiler_name>应从上面的命令中替换为受支持的profiler的名称):

sbt jsoniter-scala-benchmarkJVM/clean \' jsoniter-scala-benchmarkJVM/Jmh/run -prof <profiler_name>:help \'

对于参数基准,可以通过-p选项设置参数的常数值:

sbt jsoniter-scala-benchmarkJVM/clean \' jsoniter-scala-benchmarkJVM/Jmh/run -p size=1,10,100,1000 ArrayOf.* \'

要使用以下命令来查看生成编解码器的分配率通过GC Profiler运行基准:

sbt jsoniter-scala-benchmarkJVM/clean \' jsoniter-scala-benchmarkJVM/Jmh/run -prof gc .*Reading.* \'

<p dir=\"aut

下载源码

通过命令行克隆项目:

git clone https://github.com/plokhotnyuk/jsoniter-scala.git

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

左子网 编程相关 jsoniter scala https://www.zuozi.net/34328.html

graphql java tools
上一篇: graphql java tools
zircon
下一篇: zircon
常见问题
  • 1、自动:拍下后,点击(下载)链接即可下载;2、手动:拍下后,联系卖家发放即可或者联系官方找开发者发货。
查看详情
  • 1、源码默认交易周期:手动发货商品为1-3天,并且用户付款金额将会进入平台担保直到交易完成或者3-7天即可发放,如遇纠纷无限期延长收款金额直至纠纷解决或者退款!;
查看详情
  • 1、描述:源码描述(含标题)与实际源码不一致的(例:货不对板); 2、演示:有演示站时,与实际源码小于95%一致的(但描述中有”不保证完全一样、有变化的可能性”类似显著声明的除外); 3、发货:不发货可无理由退款; 4、安装:免费提供安装服务的源码但卖家不履行的; 5、收费:价格虚标,额外收取其他费用的(但描述中有显著声明或双方交易前有商定的除外); 6、其他:如质量方面的硬性常规问题BUG等。 注:经核实符合上述任一,均支持退款,但卖家予以积极解决问题则除外。
查看详情
  • 1、左子会对双方交易的过程及交易商品的快照进行永久存档,以确保交易的真实、有效、安全! 2、左子无法对如“永久包更新”、“永久技术支持”等类似交易之后的商家承诺做担保,请买家自行鉴别; 3、在源码同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外); 4、在没有”无任何正当退款依据”的前提下,商品写有”一旦售出,概不支持退款”等类似的声明,视为无效声明; 5、在未拍下前,双方在QQ上所商定的交易内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准); 6、因聊天记录可作为纠纷评判依据,故双方联系时,只与对方在左子上所留的QQ、手机号沟通,以防对方不承认自我承诺。 7、虽然交易产生纠纷的几率很小,但一定要保留如聊天记录、手机短信等这样的重要信息,以防产生纠纷时便于左子介入快速处理。
查看详情

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务