From: Alex Gramiak <agrambot@gmail.com>
To: Dmitry Gutov <dgutov@yandex.ru>
Cc: 31138@debbugs.gnu.org
Subject: bug#31138: Native json slower than json.el
Date: Mon, 22 Apr 2019 21:06:26 -0600 [thread overview]
Message-ID: <877ebl5sjx.fsf@gmail.com> (raw)
In-Reply-To: <12721b41-c493-8193-b820-9ab4b229f102@yandex.ru> (Dmitry Gutov's message of "Mon, 22 Apr 2019 23:05:30 +0300")
[-- Attachment #1: Type: text/plain, Size: 1263 bytes --]
Dmitry Gutov <dgutov@yandex.ru> writes:
> On 22.04.2019 22:52, Alex Gramiak wrote:
>> The following might work, though I'm not
>> sure how applicable this is now to the jansson library:
>
> Peformance patches are 200% better when they come together with benchmark
> results.
Right, I should have explained: I meant that since AFAIU the size of
json_int_t is usually going to be the same size as EMACS_INT, the same
code will usually be generated for json.c. It might bring a very slight
benefit to other parts of Emacs, but not worth fussing over.
I tried making a couple patches in other areas to json.c that I hoped
would slightly improve performance, which I'll include here for
posterity. The first one uses json_dumpb over json_dumps, but from what
I can tell using it is either slower or just within error. The second
uses the *_nocheck functions where applicable, but the results seemed to
be quite similar. I suppose this means that jansson's utf-8 checking is
performant.
Benchmark for the first patch:
(setq v ["\nasdфыв\u001f\u007ffgh\t"])
(progn (garbage-collect)
(benchmark-run-compiled 100000
(json-serialize v)))
Results for the first patch: 1.1050s applied vs. 1.1078s without.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: json_dumpb --]
[-- Type: text/x-patch, Size: 3001 bytes --]
diff --git a/configure.ac b/configure.ac
index b4a9b30691..2dba99838f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2982,6 +2982,10 @@ AC_DEFUN
if test "${HAVE_JSON}" = yes; then
AC_DEFINE(HAVE_JSON, 1, [Define if using Jansson.])
JSON_OBJ=json.o
+ OLDLIBS="$LIBS"
+ LIBS="$LIBS $JSON_LIBS"
+ AC_CHECK_FUNCS(json_dumpb)
+ LIBS="$OLDLIBS"
fi
# Windows loads libjansson dynamically
diff --git a/src/json.c b/src/json.c
index 928825e034..361581c2f4 100644
--- a/src/json.c
+++ b/src/json.c
@@ -31,7 +31,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "coding.h"
#define JSON_HAS_ERROR_CODE (JANSSON_VERSION_HEX >= 0x020B00)
-
+#undef HAVE_JSON_DUMPB
#ifdef WINDOWSNT
# include <windows.h>
# include "w32common.h"
@@ -53,6 +53,11 @@ DEF_DLL_FN (json_t *, json_integer, (json_int_t value));
DEF_DLL_FN (json_t *, json_real, (double value));
DEF_DLL_FN (json_t *, json_stringn, (const char *value, size_t len));
DEF_DLL_FN (char *, json_dumps, (const json_t *json, size_t flags));
+# ifdef HAVE_JSON_DUMPB
+DEF_DLL_FN (void, json_dumpb, (const json_t *json, char *buffer,
+ size_t size,
+ size_t flags));
+# endif
DEF_DLL_FN (int, json_dump_callback,
(const json_t *json, json_dump_callback_t callback, void *data,
size_t flags));
@@ -104,6 +109,9 @@ init_json_functions (void)
LOAD_DLL_FN (library, json_real);
LOAD_DLL_FN (library, json_stringn);
LOAD_DLL_FN (library, json_dumps);
+# ifdef HAVE_JSON_DUMPB
+ LOAD_DLL_FN (library, json_dumpb);
+# endif
LOAD_DLL_FN (library, json_dump_callback);
LOAD_DLL_FN (library, json_integer_value);
LOAD_DLL_FN (library, json_real_value);
@@ -605,6 +613,10 @@ usage: (json-serialize OBJECT &rest ARGS) */)
{
ptrdiff_t count = SPECPDL_INDEX ();
+#ifdef HAVE_JSON_DUMPB
+ USE_SAFE_ALLOCA;
+#endif
+
#ifdef WINDOWSNT
if (!json_initialized)
{
@@ -625,16 +637,34 @@ usage: (json-serialize OBJECT &rest ARGS) */)
json_parse_args (nargs - 1, args + 1, &conf, false);
json_t *json = lisp_to_json_toplevel (args[0], &conf);
- record_unwind_protect_ptr (json_release_object, json);
+#ifdef HAVE_JSON_DUMPB
+ /* Called with NULL to determine the size of buffer needed. */
+ size_t size = json_dumpb (json, NULL, 0, 0);
+ char *string = SAFE_ALLOCA (size);
+
+ size = json_dumpb (json, string, size, JSON_COMPACT);
+
+ json_release_object (json);
+
+ if (!size)
+ json_out_of_memory ();
+
+
+ return SAFE_FREE_UNBIND_TO (count, json_make_string (string, size));
+#else
/* If desired, we might want to add the following flags:
JSON_DECODE_ANY, JSON_ALLOW_NUL. */
char *string = json_dumps (json, JSON_COMPACT);
+
+ json_release_object (json);
+
if (string == NULL)
json_out_of_memory ();
record_unwind_protect_ptr (json_free, string);
return unbind_to (count, json_build_string (string));
+#endif
}
struct json_buffer_and_size
[-- Attachment #3: Type: text/plain, Size: 467 bytes --]
Benchmark for the second patch:
(setq v (with-current-buffer (find-file-noselect
"~/emacs/test/src/json-tests.el")
(vector (buffer-substring-no-properties (point-min)
(point-max)))))
(progn (garbage-collect)
(benchmark-run-compiled 1000
(json-serialize v)))
Results for the second patch: 0.7815s applied vs. 0.7962s without.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: nocheck --]
[-- Type: text/x-patch, Size: 3636 bytes --]
diff --git a/src/json.c b/src/json.c
index 928825e034..3aa6be7212 100644
--- a/src/json.c
+++ b/src/json.c
@@ -46,12 +46,14 @@ DEF_DLL_FN (size_t, json_array_size, (const json_t *array));
DEF_DLL_FN (json_t *, json_object, (void));
DEF_DLL_FN (int, json_object_set_new,
(json_t *object, const char *key, json_t *value));
+DEF_DLL_FN (int, json_object_set_new_nocheck,
+ (json_t *object, const char *key, json_t *value));
DEF_DLL_FN (json_t *, json_null, (void));
DEF_DLL_FN (json_t *, json_true, (void));
DEF_DLL_FN (json_t *, json_false, (void));
DEF_DLL_FN (json_t *, json_integer, (json_int_t value));
DEF_DLL_FN (json_t *, json_real, (double value));
-DEF_DLL_FN (json_t *, json_stringn, (const char *value, size_t len));
+DEF_DLL_FN (json_t *, json_stringn_nocheck, (const char *value, size_t len));
DEF_DLL_FN (char *, json_dumps, (const json_t *json, size_t flags));
DEF_DLL_FN (int, json_dump_callback,
(const json_t *json, json_dump_callback_t callback, void *data,
@@ -97,12 +99,13 @@ init_json_functions (void)
LOAD_DLL_FN (library, json_array_size);
LOAD_DLL_FN (library, json_object);
LOAD_DLL_FN (library, json_object_set_new);
+ LOAD_DLL_FN (library, json_object_set_new_nocheck);
LOAD_DLL_FN (library, json_null);
LOAD_DLL_FN (library, json_true);
LOAD_DLL_FN (library, json_false);
LOAD_DLL_FN (library, json_integer);
LOAD_DLL_FN (library, json_real);
- LOAD_DLL_FN (library, json_stringn);
+ LOAD_DLL_FN (library, json_stringn_nocheck);
LOAD_DLL_FN (library, json_dumps);
LOAD_DLL_FN (library, json_dump_callback);
LOAD_DLL_FN (library, json_integer_value);
@@ -131,12 +134,13 @@ init_json_functions (void)
#define json_array_size fn_json_array_size
#define json_object fn_json_object
#define json_object_set_new fn_json_object_set_new
+#define json_object_set_new_nocheck fn_json_object_set_new_nocheck
#define json_null fn_json_null
#define json_true fn_json_true
#define json_false fn_json_false
#define json_integer fn_json_integer
#define json_real fn_json_real
-#define json_stringn fn_json_stringn
+#define json_stringn_nocheck fn_json_stringn_nocheck
#define json_dumps fn_json_dumps
#define json_dump_callback fn_json_dump_callback
#define json_integer_value fn_json_integer_value
@@ -394,9 +398,10 @@ lisp_to_json_toplevel_1 (Lisp_Object lisp,
table test is not `equal'. */
if (json_object_get (json, key_str) != NULL)
wrong_type_argument (Qjson_value_p, lisp);
- int status = json_object_set_new (json, key_str,
- lisp_to_json (HASH_VALUE (h, i),
- conf));
+ int status
+ = json_object_set_new_nocheck (json, key_str,
+ lisp_to_json (HASH_VALUE (h, i),
+ conf));
if (status == -1)
{
/* A failure can be caused either by an invalid key or
@@ -508,12 +513,9 @@ lisp_to_json (Lisp_Object lisp, struct json_configuration *conf)
else if (STRINGP (lisp))
{
Lisp_Object encoded = json_encode (lisp);
- json_t *json = json_stringn (SSDATA (encoded), SBYTES (encoded));
+ json_t *json = json_stringn_nocheck (SSDATA (encoded), SBYTES (encoded));
if (json == NULL)
{
- /* A failure can be caused either by an invalid string or by
- low memory. */
- json_check_utf8 (encoded);
json_out_of_memory ();
}
return json;
next prev parent reply other threads:[~2019-04-23 3:06 UTC|newest]
Thread overview: 161+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-04-12 19:13 bug#31138: Native json slower than json.el Sebastien Chapuis
2018-04-13 7:24 ` Eli Zaretskii
2018-04-15 14:40 ` Sebastien Chapuis
2018-04-15 15:19 ` Eli Zaretskii
2019-03-23 1:59 ` Sébastien Chapuis
2019-03-23 8:15 ` Eli Zaretskii
2019-03-23 9:40 ` Eli Zaretskii
2019-03-23 12:59 ` Sébastien Chapuis
2019-03-23 13:21 ` Eli Zaretskii
2019-03-23 13:31 ` yyoncho
2019-03-23 14:00 ` Eli Zaretskii
2019-03-23 14:32 ` yyoncho
2019-03-23 14:55 ` Eli Zaretskii
2019-03-23 15:27 ` yyoncho
2019-03-23 16:29 ` Eli Zaretskii
[not found] ` <CACCVLQW=_YngoTwXU+1BDvVVy5jwxSmDFUQJBvs8=PrP=fn=aw@mail.gmail.com>
2019-03-23 18:50 ` Eli Zaretskii
2019-03-23 20:23 ` yyoncho
2019-03-23 20:54 ` Eli Zaretskii
2019-03-23 21:04 ` yyoncho
2019-03-24 3:32 ` Eli Zaretskii
2019-03-24 9:35 ` yyoncho
2019-03-24 11:20 ` Eli Zaretskii
2019-03-24 11:37 ` yyoncho
2019-03-24 15:15 ` Eli Zaretskii
2019-03-24 18:24 ` yyoncho
2019-03-24 18:28 ` Eli Zaretskii
2019-03-24 20:57 ` yyoncho
2019-03-25 3:32 ` Eli Zaretskii
2019-03-25 5:44 ` yyoncho
2019-03-25 16:42 ` Eli Zaretskii
2019-03-25 18:20 ` yyoncho
2019-03-25 18:25 ` Eli Zaretskii
2019-03-25 19:16 ` yyoncho
2019-03-25 20:05 ` Eli Zaretskii
2019-03-25 21:34 ` yyoncho
2019-03-25 23:04 ` Dmitry Gutov
2019-03-26 3:51 ` Eli Zaretskii
2019-03-26 16:14 ` Eli Zaretskii
2019-03-26 17:45 ` yyoncho
2019-03-26 18:11 ` Eli Zaretskii
2019-03-26 18:15 ` yyoncho
2019-04-16 1:36 ` Dmitry Gutov
2019-04-16 2:38 ` Eli Zaretskii
2019-04-16 13:50 ` Dmitry Gutov
2019-04-16 15:13 ` Eli Zaretskii
2019-04-16 15:30 ` Dmitry Gutov
2019-04-16 16:10 ` Eli Zaretskii
2019-04-16 16:23 ` Dmitry Gutov
2019-04-16 16:44 ` Eli Zaretskii
2019-04-21 8:58 ` Eli Zaretskii
2019-04-21 9:15 ` Dmitry Gutov
2019-04-21 9:31 ` Eli Zaretskii
2019-04-21 10:23 ` yyoncho
2019-04-21 10:37 ` Eli Zaretskii
2019-04-21 11:38 ` yyoncho
2019-04-21 12:15 ` Eli Zaretskii
2019-04-21 13:28 ` yyoncho
2019-04-21 19:03 ` Eli Zaretskii
2019-04-21 20:13 ` Eli Zaretskii
2019-04-22 5:38 ` yyoncho
2019-04-22 8:01 ` Eli Zaretskii
2019-04-22 13:00 ` yyoncho
2019-04-22 13:17 ` Eli Zaretskii
2019-04-22 16:53 ` Ivan
2019-04-22 16:58 ` Eli Zaretskii
2019-04-21 22:17 ` Dmitry Gutov
2019-04-22 7:16 ` Eli Zaretskii
2019-04-22 13:54 ` Dmitry Gutov
2019-04-22 15:24 ` Eli Zaretskii
2019-04-22 15:31 ` Dmitry Gutov
2019-04-21 12:59 ` Philipp Stephani
2019-04-21 13:09 ` yyoncho
2019-04-21 13:33 ` Philipp Stephani
2019-04-22 11:48 ` Dmitry Gutov
2019-04-22 12:12 ` Eli Zaretskii
2019-04-22 12:24 ` Dmitry Gutov
2019-04-22 13:02 ` Eli Zaretskii
2019-04-22 15:02 ` Dmitry Gutov
2019-04-22 15:36 ` Eli Zaretskii
2019-04-22 16:16 ` Dmitry Gutov
2019-04-22 16:28 ` Eli Zaretskii
2019-04-22 16:44 ` Dmitry Gutov
2019-04-22 16:50 ` Eli Zaretskii
2019-04-22 17:05 ` Dmitry Gutov
2019-04-22 17:24 ` Eli Zaretskii
2019-04-22 21:03 ` Dmitry Gutov
2019-04-23 10:22 ` Eli Zaretskii
2019-04-23 11:39 ` Dmitry Gutov
2019-04-23 13:19 ` Eli Zaretskii
2019-04-22 16:49 ` Eli Zaretskii
2019-04-22 17:11 ` Dmitry Gutov
2019-04-22 17:26 ` Eli Zaretskii
2019-04-22 22:23 ` Dmitry Gutov
2019-04-23 6:00 ` Eli Zaretskii
2019-04-23 9:46 ` Philipp Stephani
2019-04-23 10:38 ` Eli Zaretskii
2019-04-23 10:44 ` Dmitry Gutov
2019-04-24 2:23 ` Richard Stallman
2019-04-22 17:12 ` Eli Zaretskii
2019-04-22 21:00 ` Dmitry Gutov
2019-04-21 22:14 ` Dmitry Gutov
2019-04-22 7:06 ` Eli Zaretskii
2019-04-21 22:12 ` Dmitry Gutov
2019-04-22 7:03 ` Eli Zaretskii
2019-04-22 11:46 ` Dmitry Gutov
2019-04-22 12:07 ` Eli Zaretskii
2019-04-22 12:58 ` Dmitry Gutov
2019-04-22 13:12 ` Eli Zaretskii
2019-04-22 13:58 ` Dmitry Gutov
2019-04-22 15:25 ` Eli Zaretskii
2019-04-22 15:41 ` Dmitry Gutov
2019-04-22 15:50 ` Eli Zaretskii
2019-04-22 16:00 ` Dmitry Gutov
2019-04-22 16:22 ` Eli Zaretskii
2019-04-22 19:55 ` Dmitry Gutov
2019-04-22 20:28 ` Eli Zaretskii
2019-04-23 11:52 ` Dmitry Gutov
2019-04-23 12:15 ` Eli Zaretskii
2019-04-23 12:37 ` yyoncho
2019-04-23 13:09 ` Eli Zaretskii
2019-04-23 13:27 ` yyoncho
2019-04-23 14:24 ` Eli Zaretskii
2019-04-23 12:37 ` Sébastien Chapuis
2019-04-23 13:10 ` Eli Zaretskii
2019-04-23 14:22 ` Dmitry Gutov
2019-04-23 14:40 ` Philipp Stephani
2019-04-23 15:09 ` Eli Zaretskii
2019-04-23 15:17 ` Eli Zaretskii
2019-04-23 15:36 ` yyoncho
2019-04-23 15:39 ` Eli Zaretskii
2019-04-23 15:43 ` yyoncho
2019-04-23 22:34 ` Dmitry Gutov
2019-04-24 6:20 ` Eli Zaretskii
2019-04-24 6:57 ` Dmitry Gutov
2019-04-24 7:28 ` Eli Zaretskii
2019-04-24 9:52 ` Dmitry Gutov
2019-04-23 14:58 ` Eli Zaretskii
2019-04-24 15:55 ` Dmitry Gutov
2019-04-24 16:21 ` Eli Zaretskii
2019-04-24 16:46 ` Dmitry Gutov
2019-04-24 17:06 ` Eli Zaretskii
2019-04-24 17:36 ` Dmitry Gutov
2019-04-24 17:43 ` Eli Zaretskii
2019-04-24 20:25 ` Dmitry Gutov
2019-04-25 10:44 ` Eli Zaretskii
2019-04-25 14:27 ` Dmitry Gutov
2020-08-22 23:28 ` Lars Ingebrigtsen
2020-08-23 5:50 ` Eli Zaretskii
2019-04-23 14:50 ` Andy Moreton
2019-04-23 15:03 ` Eli Zaretskii
2019-04-23 15:44 ` Andy Moreton
2019-04-22 11:36 ` Dmitry Gutov
2019-04-22 12:01 ` Eli Zaretskii
2019-04-22 13:11 ` Dmitry Gutov
2019-03-30 9:07 ` Eli Zaretskii
2019-04-22 18:20 ` Alex Gramiak
2019-04-22 18:27 ` Eli Zaretskii
2019-04-22 19:52 ` Alex Gramiak
2019-04-22 20:05 ` Dmitry Gutov
2019-04-23 3:06 ` Alex Gramiak [this message]
2019-04-23 11:44 ` Dmitry Gutov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=877ebl5sjx.fsf@gmail.com \
--to=agrambot@gmail.com \
--cc=31138@debbugs.gnu.org \
--cc=dgutov@yandex.ru \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.