json 频繁使用之双刃剑

探讨了使用JSON作为聊天室中间存储介质时,不同JSON生成方法对IE内存和Apache进程内存的影响。通过实验证明,PHP内置函数相较于第三方库能更有效地控制服务器内存增长。
json 频繁使用之双刃剑

最近,弄了一个聊天室,使用json作为中间存储介质,这样在单个页面实现聊天室功能,json有好处,就是方便解析,而且json的串可以放在内存里面,这样减少了io操作,而且js解析起来也很方便,减少了语言解析的过程.采用的是js框架是jquery.
进入正文

//取得json的url地址
var url_get_json = "get.php";
function getChatList()
{
        $.getJSON(''+url_get_json+'?r='+Math.random(),function(json){createDiv(json);});
        if($('#'+form_isGotoEnd).val()==1 && $('#'+form_isGotoEnd).attr('checked')==true)
        {
        }else{
                gotoEnd();
        }
}
此函数为核心代码
调用

$("document").ready(
                function(){
                        //建立选择
                        makeSelect(div_look_chat_select,form_look_chat_select,chat_type_array,0);
                        makeSelect(div_send_chat_select,form_send_chat_select,chat_type_array,0);
                        //监听点击按钮事件
                        $('#'+form_send_button).click(function(){checkForm();});
                        //getChatList();
                        setInterval('getChatList()',1000);
                        $("#"+div_chat_send).keyup(function(e){keyup(e);});
                }               
);
//setInterval('getChatList()',1000);   这里为频繁调用  
get.php 代码

<?php
//include_once("JSON.php");
include_once("classes/FileIO.class.php");
//设置cache文件名
$cacheFile "cache/chat.data";
//聊天记录数组
$charArr = array();
if(
FileIO::isFileExists($cacheFile))
{
    
$chatStr FileIO::getFileContent($cacheFile);
    
$charArr unserialize($chatStr);
}
//echo FastJSON::encode($charArr);
//$json = new Services_JSON();
//echo $json->encode($charArr);
echo json_encode($charArr);
?>
我这个文件做了很多注释,而且这个文件的功能也不复杂,现在开启的是,php本身对json的支持函数

经过测试
1,采用 非php模块加载方式进行数组转换成json串的
ie内存使用量,无明显变化   apache 进程使用内存量,明显快速增加
2 ,采用 php模块方式 进行数组转换成json串的
ie内存使用量,无明显变化   apache 进程使用内存量,增加 但是属于缓慢增加,或者说,基本可以接受

现在说明下,为什么我会把瓶颈确定在这里
我查了下,有2种声音,一种说 频繁的ajax请求,造成js使用ie内存不段增加,解决办法是js的内存回收机制
我观察了下,我ie的内存使用量,没有明显的增加,也就是说,我没用产生 ajax请求浪费,还有就是我使用的是jquery,应该这个框架是靠的住的。不过说实话,我读了下代码,ajax请求过度,释放的问题我解决不了。那好,我做测试
大家可以看到 getChatList() 这个函数里,我吧请求回来的json给了 createDiv(json) 来处理,我这个函数就写成 function createDiv(json){rerurn false}
如果是ajax请求过度,那么内存的量应该会下来,我测试,没有好转,内存使用依然快速增加。那好我注释掉了,json的请求,内存使用平缓。
那问题就在这里,那好,我修改了,我的get.php 文件,修改成

<?php
$json 
= new Services_JSON();
echo 
$json->encode(array());
?>
这样内存使用基本平缓 修改成使用的样子,内存快速增加
这就说明,是 生成js编码的情况下,造成了,apache的内存使用快速增加,并不是ajax请求过度造成的
以上大家可以测试。

问题,我也想不明白的原因,同样是json串的生成,就算是php 模块加载形式,也只是生成了json的格式,并没有其他什么情况,为什么使用可以保持服务器内存的稳定,而采用php语言来生成的json方式,就不能成呢? 这个需要明白php内存使用的人来解释下了。

我上面的方案,比较极端,因为get.php文件会被频繁调用,所以内存使用上看起来更明显些。

把json串的生成直接放到post.php里,是个好的方案,get.php只提供文件读取,这样更好一些,但是上面的问题依然存在。

作者 :叁石
blog : http://blog.youkuaiyun.com/sanshi0815
mail : sanshi0815@tom.com
 
``` const url = "https://models.youkuaiyun.com/v1/chat/completions" const API_KEY = 'sk-yeaxrzuqufgtkqnvmdzszrsahlaaiyfxmezciiugkpfrs' const headers = { "Authorization": `Bearer ${API_KEY}`, 'Content-Type': 'application/json' }; const params = { "model": 'Deepseek-R1', "messages": [ { "role": "user", "content": this.content, } ], "stream": true, } const response = await fetch(url, { method: 'POST', headers: headers, body: JSON.stringify(params) }) // 检查响应状态 if (!response.ok || response.status != 200) { return } // 获取响应体的读取器 const reader = response.body.getReader() console.log(reader); // 创建UTF-8解码器 const decoder = new TextDecoder('utf-8'); let done = false;// 标记是否已读取完所有数据 let buffer = ''; // 用于缓存未完成的数据 // 循环读取数据直到完成 while (!done) { // 从读取器中读取下一个值 const { value, done: doneReading } = await reader.read(); done = doneReading;// 更新done标记 // 将读取到的字节数据解码为字符串,并根据是否是最后一个块进行拼接 buffer += decoder.decode(value, { stream: !done }); let start; while ((start = buffer.indexOf('data:')) !== -1) { const end = buffer.indexOf('\n', start); if (end === -1) break; // 如果没有找到结束符,则等待更多数据 const chunk = buffer.substring(start + 5, end).trim(); // 获取'data:'之后的内容 buffer = buffer.substring(end + 1); // 更新buffer为剩余部分 const data = JSON.parse(chunk); // 分解出content内容 data为每次输出choices if (data.choices && Array.isArray(data.choices)) { let fullContent = ''; // 存储完整的内容 let thinkingFullContent = ''; // 存储完整的R1思路内容 let isStreamEnd = false; // 标记是否是流结束 // 遍历每个choices来构建完整content内容 for (const choice of data.choices) { // 如果存在delta和其下的content回复内容,加入fullContent if (choice.delta && choice.delta.content) { fullContent += choice.delta.content; } // 同上 收集R1思考内容 if (choice.delta && choice.delta.reasoning_content) { thinkingFullContent += choice.delta.reasoning_content; } // 检查是否有finish_reason为stop的情况,表示流结束 if (choice.finish_reason === 'stop') { isStreamEnd= true; } } // R1思考输出内容 if (data.id && thinkingFullContent){ for (const char of thinkingFullContent) { this.talkList[responseIndex].thinkingContent += char; await new Promise(resolve => setTimeout(resolve, 20)); } } if (data.id && fullContent) { this.delay(timer); this.talkList[responseIndex].thinkingload = false; // 回复内容有值即关闭R1思考 // 流式处理 逐个添加字符 for (const char of fullContent) { this.talkList[responseIndex].content += char; await new Promise(resolve => setTimeout(resolve, 20)); // 控制输出速度 } // 如果检测到流结束,则取消读取器 if (isStreamEnd) { setTimeout(() => { console.log("Message stream ended."); reader.cancel(); // 可选:取消读取器 this.scrollToBottom(); }, 1000); } } } } } }```这个里面为什么流输出完后再进行流式打字输出 为什么不是接口实时输出 后面直接边打字边跟着输出
03-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值