Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JsonHelper usage in all NGSIv2 renders (second step: optimization and performance) #1298

Open
fgalan opened this issue Sep 29, 2015 · 18 comments
Assignees
Milestone

Comments

@fgalan
Copy link
Member

fgalan commented Sep 29, 2015

JsonHelper class was introduced in PR #1284 as a way of simplifying the JSON response rendering (at that time only used in the JSON response for the "get all entities" operations). In addition, the class allows to rendering logic in a common place, which is interesting as it allows to solve problems such the one described in #1172 in a single point.

This issue is about extending the usage of JsonHelper to the other NGSIv2 types (and adapt the JsonHelper class in the process, if needed). As a result, we should see a reduction of the length and complexity of the current render() methods, as the start to use addRaw(), addString().

Effort: 5 man day

@kzangeli
Copy link
Member

Before making this big change, that definitely has its advantages, we need to make sure the broker doesn't loose too much in terms of throughput.

@fgalan
Copy link
Member Author

fgalan commented Sep 29, 2015

Actually, what we have to check is not only the change in throughput, but the trade off between throughput and code simplification (i.e. small loss in throughput is acceptable if the gain in code simplification is big).

@kzangeli
Copy link
Member

Yes, that is exactly what I said :-)

@fgalan fgalan added this to the 0.26.0 milestone Sep 30, 2015
@fgalan fgalan modified the milestones: 0.26.0, 0.27.0, 0.28.0 Oct 28, 2015
@fgalan fgalan modified the milestones: 0.28.0, 0.29.0 Dec 1, 2015
@fgalan fgalan modified the milestones: 0.29.0, 0.30.0 Feb 4, 2016
@fgalan fgalan modified the milestones: 1.1.0, 1.2.0 Mar 17, 2016
@fgalan
Copy link
Member Author

fgalan commented Jun 28, 2018

With regards to payload rendering two actions needs to be done.

A first action is related with unification and simplification. Due to the organic evolution of the code during years, we have ended with several ways of rendering payloads. We should have ONLY ONE pattern along all code. Having only one pattern will be a big gain in simplification and homogeneity and will allow to focus optimizations (related with the second action described in this comment, see below) in just one point.

The pattern to use should be the one based in the JsonHelper.h API (used at the current code for instance in Subscription::toJson() or Registrations::toJson()). The approach of composing the document to render using “add” methods, then getting the string corresponding to the final composition is very powerful in terms of simplicity of use and frees the developer of dealing directly with start/ending tags, commas and all that delicate and distracting stuff.

The second action is related with optimization and performance. JsonHelper implementation (JsonHelper.cpp) is based in an internal buffer, currently implemented using a std::ostringstream object. However, there are alternatives:

  • std::ostringstream (the one currently used)
  • rapidjson (inspired in @aarranz's PR Unify json serialization by using rapidjson #2960)
  • std::string (similar to the way old render() and toJson() code work)
  • static char array
  • dynamic char array (starting with an initial size large enough to cover most of the cases, but able to grow if needed)

The different implementation alternatives would be internal modifications to JsonHelper.cpp and will not modify the JsonHelper.h API exported to other functions. During the optimitization work each implementation could live in a separated branch.

This work will be fact-driven based in performance testing and comparison. Thus, metrics for the different implementation alternatives will be obtained based in the same scenario. That scenario should be one in which the payload rendering has an important impact, e.g. populate DB with 1000 large elements (entities or registrations), then GET them with ?limit=1000. Examples based in apache benchmark:

ab -c 40 -n 50000 http://fiware-centos1:1026/v2/entities?limit=1000
ab -c 40 -n 50000 http://fiware-centos1:1026/v2/registrations?limit=1000

Running CB as:

contextBroker  -fg -noCache -disableMetrics -reqMutexPolicy none

with an index for creDate in the DB.

@fgalan
Copy link
Member Author

fgalan commented Jun 28, 2018

Note that both actions are independent. I mean, the work can start extending the JsonHelper.h usage to all renders which are not currently using it. Or, on the contrary, the JsonHelper.cpp implementation can be optimized based on testing the payloads that currently are using it (registrations, for instance).

@fgalan
Copy link
Member Author

fgalan commented Jun 28, 2018

With regards to unification and simplification action, NGSIv1 renders may be left apart and stay as they are now. NGSIv1 is semi-deprecated code, so effort invested on it is semi-wasted.

@fgalan
Copy link
Member Author

fgalan commented Aug 31, 2018

This new bug #3280 raises the importance of progressing in this issue. Thus, as a first step I'd suggest a PR doing the following:

  1. Change JsonHelper.cpp implementation in order to use std::string concatenation approach (the current one used in entities rendering) instead of std::ostringstream
  2. Change NGSIv2 renders for entities/attributes/metadata to use the new implementation of JsonHelper

That PR should hopefully fix also #3280

@fgalan
Copy link
Member Author

fgalan commented Sep 5, 2018

PR #3285 addresses this issue (but probably more ones will follow).

@fgalan
Copy link
Member Author

fgalan commented Sep 12, 2018

PR #3292 continues the simplification work.

@fgalan
Copy link
Member Author

fgalan commented Sep 21, 2018

PR #3301 continues simplification work (unification of ContextElement and Entity classes)

@fgalan
Copy link
Member Author

fgalan commented Oct 1, 2018

PR #3324 continues simplification work: removal os never implemented idDomain and reg metadata in NGSIv1 and renaming render() to toJsonV1().

@fgalan
Copy link
Member Author

fgalan commented Oct 3, 2018

PR #3329 continues simplifciation work (see PR body for details)

@fgalan
Copy link
Member Author

fgalan commented Oct 3, 2018

Raised in PR #3329 (actually, raised in previously, but we have remember when discussing that PR :):

A more powerfull approach (to plain JsonHelper) would be to have only one helper object, passing in down all along the toJson() functions

Maybe that object could be an instance of a rapidjson tree

@fgalan
Copy link
Member Author

fgalan commented Oct 5, 2018

PR #3330 unified ContextElementVector into EntityVector

@fgalan
Copy link
Member Author

fgalan commented Oct 10, 2018

PR #3336 ensures that old JSON_ macros are using only in the NGSIv1 renderint part.

@fgalan
Copy link
Member Author

fgalan commented Oct 10, 2018

Fixes in devel manual done in PR #3339

AlvaroVega added a commit that referenced this issue Oct 10, 2018
AlvaroVega added a commit that referenced this issue Oct 15, 2018
Fix devel manual after changes implemented as part of #1298
fgalan added a commit that referenced this issue Oct 16, 2018
(JP) Fix devel manual after changes implemented as part of #1298
@fgalan
Copy link
Member Author

fgalan commented Jul 6, 2022

With regards to the two steps described in this previous comment I'd say that at the present momento (3.7.0) the unification and simplification was completed time ago.

Thus, the pending item of this work on this issue would be optimization and performance. I'll change issue title to properly align with this scope.

@fgalan fgalan changed the title JsonHelper usage in all NGSIv2 renders JsonHelper usage in all NGSIv2 renders (second step: optimization and performance) Jul 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants