gob_json_test.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. package encoding
  2. import (
  3. "bytes"
  4. "encoding/gob"
  5. "encoding/json"
  6. "testing"
  7. "time"
  8. "github.com/fxamacker/cbor/v2"
  9. "github.com/langgenius/dify-plugin-daemon/internal/utils/parser"
  10. "github.com/langgenius/dify-plugin-daemon/pkg/entities/constants"
  11. "github.com/langgenius/dify-plugin-daemon/pkg/entities/manifest_entities"
  12. "github.com/langgenius/dify-plugin-daemon/pkg/entities/plugin_entities"
  13. "github.com/langgenius/dify-plugin-daemon/tests"
  14. "github.com/vmihailenco/msgpack/v5"
  15. )
  16. func BenchmarkMsgpackVsJson(b *testing.B) {
  17. declaration := plugin_entities.PluginDeclaration{
  18. PluginDeclarationWithoutAdvancedFields: plugin_entities.PluginDeclarationWithoutAdvancedFields{
  19. Version: "0.0.1",
  20. Type: manifest_entities.PluginType,
  21. Description: plugin_entities.I18nObject{
  22. EnUS: "test",
  23. },
  24. Name: "test",
  25. Icon: "test.svg",
  26. Label: plugin_entities.I18nObject{
  27. EnUS: "test",
  28. },
  29. Author: "test",
  30. CreatedAt: time.Now(),
  31. Resource: plugin_entities.PluginResourceRequirement{
  32. Memory: 1,
  33. Permission: &plugin_entities.PluginPermissionRequirement{
  34. Tool: &plugin_entities.PluginPermissionToolRequirement{
  35. Enabled: true,
  36. },
  37. Model: &plugin_entities.PluginPermissionModelRequirement{
  38. Enabled: true,
  39. },
  40. Node: &plugin_entities.PluginPermissionNodeRequirement{
  41. Enabled: true,
  42. },
  43. Storage: &plugin_entities.PluginPermissionStorageRequirement{
  44. Enabled: true,
  45. Size: 1024,
  46. },
  47. },
  48. },
  49. Plugins: plugin_entities.PluginExtensions{},
  50. Meta: plugin_entities.PluginMeta{
  51. Version: "0.0.1",
  52. Arch: []constants.Arch{
  53. constants.AMD64,
  54. },
  55. Runner: plugin_entities.PluginRunner{
  56. Language: constants.Python,
  57. Version: "3.12",
  58. Entrypoint: "main",
  59. },
  60. },
  61. },
  62. Model: &plugin_entities.ModelProviderDeclaration{
  63. Provider: "test",
  64. Label: plugin_entities.I18nObject{
  65. EnUS: "test",
  66. },
  67. Description: &plugin_entities.I18nObject{
  68. EnUS: "test",
  69. },
  70. IconSmall: &plugin_entities.I18nObject{
  71. EnUS: "test",
  72. },
  73. IconLarge: &plugin_entities.I18nObject{
  74. EnUS: "test",
  75. },
  76. ProviderCredentialSchema: &plugin_entities.ModelProviderCredentialSchema{
  77. CredentialFormSchemas: []plugin_entities.ModelProviderCredentialFormSchema{
  78. {
  79. Variable: "test",
  80. Label: plugin_entities.I18nObject{
  81. EnUS: "test",
  82. },
  83. },
  84. },
  85. },
  86. Models: []plugin_entities.ModelDeclaration{},
  87. },
  88. }
  89. // add 100 models to the declaration
  90. for i := 0; i < 100; i++ {
  91. declaration.Model.Models = append(declaration.Model.Models, plugin_entities.ModelDeclaration{
  92. Model: "test",
  93. Label: plugin_entities.I18nObject{
  94. EnUS: "test",
  95. },
  96. ModelProperties: map[string]any{
  97. "test": "test",
  98. },
  99. ParameterRules: []plugin_entities.ModelParameterRule{
  100. {
  101. Name: "test",
  102. Label: &plugin_entities.I18nObject{
  103. EnUS: "test",
  104. },
  105. Type: parser.ToPtr(plugin_entities.PARAMETER_TYPE_BOOLEAN),
  106. Required: true,
  107. Help: &plugin_entities.I18nObject{
  108. EnUS: "test",
  109. },
  110. },
  111. {
  112. Name: "test1",
  113. Label: &plugin_entities.I18nObject{
  114. EnUS: "test",
  115. },
  116. Type: parser.ToPtr(plugin_entities.PARAMETER_TYPE_BOOLEAN),
  117. Required: true,
  118. Help: &plugin_entities.I18nObject{
  119. EnUS: "test",
  120. },
  121. },
  122. {
  123. Name: "test2",
  124. Label: &plugin_entities.I18nObject{
  125. EnUS: "test",
  126. },
  127. Type: parser.ToPtr(plugin_entities.PARAMETER_TYPE_BOOLEAN),
  128. Required: true,
  129. Help: &plugin_entities.I18nObject{
  130. EnUS: "test",
  131. },
  132. },
  133. {
  134. Name: "test3",
  135. Label: &plugin_entities.I18nObject{
  136. EnUS: "test",
  137. },
  138. Type: parser.ToPtr(plugin_entities.PARAMETER_TYPE_BOOLEAN),
  139. Required: true,
  140. Help: &plugin_entities.I18nObject{
  141. EnUS: "test",
  142. },
  143. },
  144. },
  145. })
  146. }
  147. var msgpackBytes []byte
  148. var jsonBytes []byte
  149. var cborBytes []byte
  150. var gobBytes []byte
  151. totalBytes := 0
  152. // Encode benchmarks
  153. b.Run("Msgpack Encode", func(b *testing.B) {
  154. for i := 0; i < b.N; i++ {
  155. var err error
  156. msgpackBytes, err = msgpack.Marshal(declaration)
  157. if err != nil {
  158. b.Fatal(err)
  159. }
  160. totalBytes += len(msgpackBytes)
  161. }
  162. })
  163. b.Log("Msgpack encoded size:", tests.ReadableBytes(len(msgpackBytes)))
  164. b.Log("Total bytes encoded with Msgpack:", tests.ReadableBytes(totalBytes))
  165. totalBytes = 0
  166. b.Run("Json Encode", func(b *testing.B) {
  167. for i := 0; i < b.N; i++ {
  168. var err error
  169. jsonBytes, err = json.Marshal(declaration)
  170. if err != nil {
  171. b.Fatal(err)
  172. }
  173. totalBytes += len(jsonBytes)
  174. }
  175. })
  176. b.Log("Json encoded size:", tests.ReadableBytes(len(jsonBytes)))
  177. b.Log("Total bytes encoded with Json:", tests.ReadableBytes(totalBytes))
  178. totalBytes = 0
  179. b.Run("CBOR Encode", func(b *testing.B) {
  180. for i := 0; i < b.N; i++ {
  181. var err error
  182. cborBytes, err = cbor.Marshal(declaration)
  183. if err != nil {
  184. b.Fatal(err)
  185. }
  186. totalBytes += len(cborBytes)
  187. }
  188. })
  189. b.Log("CBOR encoded size:", tests.ReadableBytes(len(cborBytes)))
  190. b.Log("Total bytes encoded with CBOR:", tests.ReadableBytes(totalBytes))
  191. totalBytes = 0
  192. b.Run("GOB Encode", func(b *testing.B) {
  193. for i := 0; i < b.N; i++ {
  194. var err error
  195. var buffer bytes.Buffer
  196. enc := gob.NewEncoder(&buffer)
  197. err = enc.Encode(declaration)
  198. if err != nil {
  199. b.Fatal(err)
  200. }
  201. gobBytes = buffer.Bytes()
  202. totalBytes += len(gobBytes)
  203. }
  204. })
  205. b.Log("GOB encoded size:", tests.ReadableBytes(len(gobBytes)))
  206. b.Log("Total bytes encoded with GOB:", tests.ReadableBytes(totalBytes))
  207. // Decode benchmarks
  208. totalBytes = 0
  209. b.Run("Msgpack Decode", func(b *testing.B) {
  210. for i := 0; i < b.N; i++ {
  211. err := msgpack.Unmarshal(msgpackBytes, &declaration)
  212. if err != nil {
  213. b.Fatal(err)
  214. }
  215. totalBytes += len(msgpackBytes)
  216. }
  217. })
  218. b.Log("Total bytes decoded with Msgpack:", tests.ReadableBytes(totalBytes))
  219. totalBytes = 0
  220. b.Run("Json Decode", func(b *testing.B) {
  221. for i := 0; i < b.N; i++ {
  222. var err error
  223. var decodedDeclaration plugin_entities.PluginDeclaration
  224. err = json.Unmarshal(jsonBytes, &decodedDeclaration)
  225. if err != nil {
  226. b.Fatal(err)
  227. }
  228. totalBytes += len(jsonBytes)
  229. }
  230. })
  231. b.Log("Total bytes decoded with Json:", tests.ReadableBytes(totalBytes))
  232. totalBytes = 0
  233. b.Run("CBOR Decode", func(b *testing.B) {
  234. for i := 0; i < b.N; i++ {
  235. var decodedDeclaration plugin_entities.PluginDeclaration
  236. err := cbor.Unmarshal(cborBytes, &decodedDeclaration)
  237. if err != nil {
  238. b.Fatal(err)
  239. }
  240. totalBytes += len(cborBytes)
  241. }
  242. })
  243. b.Log("Total bytes decoded with CBOR:", tests.ReadableBytes(totalBytes))
  244. totalBytes = 0
  245. b.Run("GOB Decode", func(b *testing.B) {
  246. for i := 0; i < b.N; i++ {
  247. var decodedDeclaration plugin_entities.PluginDeclaration
  248. dec := gob.NewDecoder(bytes.NewBuffer(gobBytes))
  249. err := dec.Decode(&decodedDeclaration)
  250. if err != nil {
  251. b.Fatal(err)
  252. }
  253. totalBytes += len(gobBytes)
  254. }
  255. })
  256. b.Log("Total bytes decoded with GOB:", tests.ReadableBytes(totalBytes))
  257. totalBytes = 0
  258. b.Run("Map Json Decode", func(b *testing.B) {
  259. for i := 0; i < b.N; i++ {
  260. var decoded map[string]any
  261. err := json.Unmarshal(jsonBytes, &decoded)
  262. if err != nil {
  263. b.Fatal(err)
  264. }
  265. totalBytes += len(jsonBytes)
  266. }
  267. })
  268. b.Log("Total map bytes decoded with Json:", tests.ReadableBytes(totalBytes))
  269. }