我在javascript中有一个非常大的对象(大约10MB)。
当我对它进行字符串化时,它需要很长时间,所以我将它发送到后端并将其解析为一个对象(实际上是带有数组的嵌套对象),这也需要很长时间,但这不是我们在这个问题中的问题。
问题:
如何让JSON.stringify
更快,任何想法或替代方案,我需要一个javaScript解决方案,我可以使用的库或想法。
我尝试了什么
我google了很多,看起来没有比JSON.stringify
更好的表现,或者我的谷歌搜索技能生锈了!
结果
我接受任何可以解决我在请求中长时间保存(发送到后端)的建议(我知道它的大请求)。
代码问题示例(有关问题的详细信息)
Request URL:http://localhost:8081/systemName/controllerA/update.html;jsessionid=FB3848B6C0F4AD9873EA12DBE61E6008
Request Method:POST
Status Code:200 OK
我发送POST给后端,然后发送到 JAVA
的request.getParameter( “BigPostParameter”)
我读了它以使用
转换为对象 public boolean fromJSON(String string) {
if (string != null && !string.isEmpty()) {
ObjectMapper json = new ObjectMapper();
DateFormat dateFormat = new SimpleDateFormat(YYYY_MM_DD_T_HH_MM_SS_SSS_Z);
dateFormat.setTimeZone(TimeZone.getDefault());
json.setDateFormat(dateFormat);
json.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
WebObject object;
// Logger.getLogger("JSON Tracker").log(Level.SEVERE, "Start");
try {
object = json.readValue(string, this.getClass());
} catch (IOException ex) {
Logger.getLogger(JSON_ERROR).log(Level.SEVERE, "JSON Error: {0}", ex.getMessage());
return false;
}
// Logger.getLogger("JSON Tracker").log(Level.SEVERE, "END");
return this.setThis(object);
}
return false;
}
赞这个
BigObject someObj = new BigObject();
someObj.fromJSON(request.getParameter("BigPostParameter"))
P.S :仅此一行object = json.readValue(string, this.getClass());
也非常非常慢。
再次总结
发布时间问题(stringify)JavaScript瓶子缺口。
解析那个字符串化成对象的另一个问题(使用jackson),主要是我将svg标记内容作为样式列在该字符串化对象中,其他列是字符串,int主要是
答案 0 :(得分:2)
正如评论者所说-无法加快解析速度。
如果担心的是应用程序在进行字符串化/解析时被阻止,则尝试将数据拆分为单独的对象,对其进行严格的字符串化处理,然后组合回一个对象,然后再保存到服务器上。
如果应用程序的加载时间不是问题,则可以尝试在现有应用程序之上进行临时的增量更改。
我使用json-diff https://github.com/andreyvit/json-diff来计算更改,并且类似物很少。
答案 1 :(得分:0)
解析是一个缓慢的过程。如果要发布10MB的对象,请将其转换为文件,blob或缓冲区。使用formdata而不是application / json和application / x-www-form-urlencoded发送该文件/ blob / buffer。
答案 2 :(得分:0)
就像大多数“可重复的”大问题一样,您可以使用异步!
但是,等等,即使异步,JS还是不是单线程的吗?是的……但是您可以使用 Service-Workers 来获取真值通过并行化过程,更快地异步和序列化对象。
//= Functions / Classes =============================================================|
// To tell JSON stringify that this is already processed, don't touch
class SerializedChunk {
constructor(data){this.data = data}
toJSON() {return this.data}
}
// Attach all events and props we need on workers to handle this use case
const mapCommonBindings = w => {
w.addEventListener('message', e => w._res(e.data), false)
w.addEventListener('error', e => w._rej(e.data), false)
w.solve = obj => {
w._state && await w._state.catch(_=>_) // Wait for any older tasks to complete if there is another queued
w._state = new Promise((_res, _rej) => {
// Give this object promise bindings that can be handled by the event bindings
// (just make sure not to fire 2 errors or 2 messages at the same time)
Object.assign(w, {_res, _rej})
})
w.postMessage(obj)
return await w._state // Return the final output, when we get the `message` event
}
}
//= Initialization ===================================================================|
// Let's make our 10 workers
const workers = Array(10).fill(0).map(_ => new Worker('worker.js'))
workers.forEach(mapCommonBindings)
// A helper function that schedules workers in a round-robin
workers.schedule = async task => {
workers._c = ((workers._c || -1) + 1) % workers.length
const worker = workers[workers._c]
return await worker.solve(task)
}
// A helper used below that takes an object key, value pair and uses a worker to solve it
const _asyncHandleValuePair = async ([key, value]) => [key, new SerializedChunk(
await workers.schedule(value)
)]
//= Final Function ===================================================================|
// The new function (You could improve the runtime by changing how this function schedules tasks)
// Note! This is async now, obviously
const jsonStringifyThreaded = async o => {
const f_pairs = await Promise.all(Object.entries(o).map(_asyncHandleValuePair))
// Take all final processed pairs, create a new object, JSON stringify top level
final = f_pairs.reduce((o, ([key, chunk]) => (
o[key] = chunk, // Add current key / chunk to object
o // Return the object to next reduce
), {}) // Seed empty object that will contain all the data
return JSON.stringify(final)
}
/* lot of other code, till the function that actually uses this code */
async function submitter() {
// other stuff
const payload = await jsonStringifyThreaded(input.value)
await server.send(payload)
console.log('Done!')
}
self.addEventListener('message', function(e) {
const obj = e.data
self.postMessage(JSON.stringify(obj))
}, false)
这可以通过以下方式进行:
async .solve(Object): String
,它使用承诺解决了我们的任务,同时掩盖了回调地狱async jsonStringifyThreaded(Object): String
,该方法异步执行JSON.stringify
SerializedChunk
照原样使用的JSON.stringify
,而不尝试处理(因为它具有.toJSON()
)您可能还需要考虑一些其他事情来提高性能:
jsonStringifyThreaded()
,以在更深层次上安排更多对象。答案 3 :(得分:0)
您可以探索诸如fast-json-stringify之类的库,这些库使用模板架构,并在转换json对象时使用它,以提高性能。检查以下文章。
https://developpaper.com/how-to-improve-the-performance-of-json-stringify/