记C#优化接口速度过程

前提摘要
首先这个项目是接手的前一任先写的项目,接手后,要求对项目一些速度相对较慢的接口进行优化,到第一个速度比较慢的接口后,发现单接口耗时4-8秒,是的,请求同一个接口,在参数不变的情况下,会出现浮动的时长,这种,之前我在其他项目里面也遇到过,第一种是因为有其他用户在操作其他比较卡的接口时,或者导出报表时,造成接口卡顿的拥堵,这种情况没有办法去排查,只能一一把接口优化好,速度才能提上来**,第二种想到的是检测服务,如果服务跑的时候间隔时间较短**,然后又有大量的查询之类的,可能也会造成整体性能的低下,这种可以排查,检查服务确实有一分钟跑一次的服务,但是,查询不大,按理来说,应该痛点不是在这里
随后对该接口进行优化,首先是对数据库查询类的代码进行优化,将查询语句一一挑出来,之后再放到数据库中去排查查询速度比较慢的查询,但是未发现查询比较慢的查询,于是就只能先把缺掉的索引先补上,在检查数据库查询类的代码的时候,发现这个接口存在多次连接数据库查询数据,大概有20-30次,很明显是个隐患,这个地方肯定会有拖累速度,考虑到重写的话,首先是不熟悉业务流程,第二是可能需要花费大量时间,所以还是争取在不改变原来的逻辑下,去给接口进行优化,所以查询多次的问题就先放一放了,随后我给重点查询的地方添加上了计时,想通过此方法来找出耗时比较明显的查询再针对性的去进行优化
Stopwatch watch = new Stopwatch();
watch.Start();
//代码
watch.Stop();
//获取检测时长1
watch.ElapsedMilliseconds
watch.Start();
//代码
watch.Stop();
//获取检测时长2
watch.ElapsedMilliseconds
通过Stopwatch很快就发现

整个检测时间下来,整个接口跑完,都不到200ms,我觉得很奇怪,既然接口整体完成速度不到200ms,为何返回给postman的速度达到了惊人的几秒钟,此时我怀疑Stopwatch不准确,于是在代码开始前和开始后都加上了datetime.now,但是显示时间也很短
猜测1:计时不准
猜测2:返回json给前端的时候,时间耗费了很长
猜测1没有办法求证,猜测2其实做了那么多项目,其实也没有遇到,而且感觉这个接口返回的json也没有那么离谱,随后就只能抱着试一试的态度,设定了以下几组返回的json,以及他们最终测试的结果
第一种 返回原来的json 结果:几秒
第二种 返回一个字符串 结果:100-200毫秒
第三种 返回原来的json,但是减少一些很长的对象 结果:几秒
第四种 返回的对象再包一层 结果:几秒
第五种 不使用框架的json返回方法,自定义json返回方法 结果:几秒
很显然第二种的出现,让我认为json返回就是接口超时的最大原因,这里我只能去猜测
第一种 这里我只能去猜测是不是服务器的内存不够,造成的返回json时这么慢
第二种 会不会是c#识别到我没有用上面代码中的参数,所以它自己省略了上面一些代码的逻辑,直接就返回了字符串,但是日志记录到了每个节点的计时,而且这个结果跟一直计时的也对的上,那就只能往下求证
然后把返回的json最小化,这时候就用到了json压缩
后端代码
//data为需要转换的数据
public string GetJsonData<T>(T data)
{// 序列化数据为JSONstring json = JsonConvert.SerializeObject(data);// 如果需要压缩using (var memoryStream = new MemoryStream()){using (var gzipStream = new GZipStream(memoryStream, CompressionMode.Compress))using (var streamWriter = new StreamWriter(gzipStream)){streamWriter.Write(json);}return Convert.ToBase64String(memoryStream.ToArray());}
}
vue
npm install pako
import pako from 'pako'
// b64Data-->传入加密的数据进行解密
function unzip (b64Data) {let strData = atob(b64Data)// Convert binary string to character-number arrayconst charData = strData.split('').map(function (x) { return x.charCodeAt(0) })// Turn number array into byte-arrayconst binData = new Uint8Array(charData)// // unzipconst data = pako.inflate(binData)// Convert gunzipped byteArray back to ascii string:strData = String.fromCharCode.apply(null, new Uint16Array(data))return strData
}// 加密
function zip (str) {if (typeof str !== 'string') {str = JSON.stringify(str)}const binaryString = pako.gzip(str, { to: 'string' })return btoa(binaryString)
}这种会中文乱码,需要改一下let strData = atob(拿到的数据)
const charData = strData.split('').map(function (x) { return x.charCodeAt(0) })
const binData = new Uint8Array(charData)
strData = pako.inflate(binData,{to: 'string'})
//转换为json对象
ret.data = JSON.parse(strData);
这样整个压缩就结束了,3.2k的字符大概能压到2.几K,三分之一吧,至于查询速度,丝毫没有减少,那只能再看看,能不能继续减少json中的字符,如果这条路行不通的话
1.后面可能会把查询修改为存储过程
2.重构数据结构,优化查询频率之类的
整个过程下来,其实测试站速度很快,慢的也就是正式站,但是两个服务器的配置不同,这个没法横向比较,测试站数据量也没有正式站多,而且测试站的服务应该不是一直在跑的
破案了
破案了,是上一任小伙伴把一个实体的扩展方法内,返回字段的时候,做了很慢的查询,之前没发现是因为,之前只是查询了这张表,但是没有用这个字段,但是在返回json的时候,返回的是整个实体,导致它会去拿所有的字段,包括扩展类中的那个很慢查询的字段,所以,会导致看起来好像是json返回很慢的感觉,也算是个坑吧
相关文章:
记C#优化接口速度过程
前提摘要 首先这个项目是接手的前一任先写的项目,接手后,要求对项目一些速度相对较慢的接口进行优化,到第一个速度比较慢的接口后,发现单接口耗时4-8秒,是的,请求同一个接口,在参数不变的情况下…...
windows环境如何运行python/java后台服务器进程而不显示控制台窗口
1.通常我们在windows环境下使用Java或Python语言编写服务器程序,都希望他在后台运行,不要显示黑乎乎的控制台窗口: 2.有人写了一个bat文件: cd /d D:\lottery\server && python .\main.py 放到了开机自启动里,可是开机的…...
记周末百度云防御CC攻击事件
今天一早,收到百度智能云短信提醒,一位客户的网站遭遇了CC攻击。 主机吧赶紧登陆客户网站查看,是否正常,看是否需要通知客户。 结果打开正常,看情况并没什么影响,那就等攻击结果了再看吧。 下午的时候&am…...
vue中v-bind控制class和style
当使用v-bind指令控制class和style时,可以通过动态绑定的方式根据不同的条件来添加或移除class,以及改变元素的样式。 1. 控制class 通过v-bind:class可以动态绑定class属性。可以使用对象语法、数组语法或者计算属性来实现。 对象语法:使用…...
【面试经典150题】【双指针】392. 判断子序列
题目链接 https://leetcode.cn/problems/is-subsequence/?envTypestudy-plan-v2&envIdtop-interview-150 题解思路 首先如果s的长度大于t的长度,那么s肯定不是t的子序列如果s的长度等于t的长度,那么st的情况下s才是t的子序列如果s的长度小于t的长…...
禁用PS/Photoshop等一系列Adobe旗下软件联网外传用户数据操作
方案一: 下载火绒杀毒,在联网请求上禁用Adobe软件的联网请求,甚至还可以额外发现哪些是它要想要偷偷摸摸干的。 方案二: 最后注意: 用盗版软件只是获得了使用权!...
C语言猜输赢游戏
目录 开头游戏的程序游戏的流程图结尾 开头 大家好,我叫这是我58,现在,请你看一下下面的游戏程序。 游戏的程序 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <Windows.h> int main() {int i 1;int ia 0…...
Rust 异步 trait 的实现困难
在 Rust 中,异步编程是使用 async/await 语法来实现的。与传统的同步编程不同,异步编程涉及到的特性较多,其中一个重要的特性是异步 trait。 异步 trait 是具有异步方法的 trait。在 Rust 中,trait 方法默认是同步的,…...
腾讯云和windows11安装frp,实现内网穿透
一、内网穿透目的 实现公网上,访问到windows上启动的web服务 二、内网穿透的环境准备 公网服务器、windows11的电脑、frp软件(需要准备两个软件,一个是安装到公网服务器上的,一个是安装到windows上的) frp下载地址下载版本 1.此版本(老版…...
Solidity智能合约事件(event)
文章目录 Solidity智能合约事件(event)什么是event事件event有什么作用日志内容位于区块链的什么地方?【重要】以太坊交易获取如何在 Solidity 中使用事件?参考 Solidity智能合约事件(event) 什么是event EVM有一个日志功能,用于将数据“写…...
第2章 Rust初体验7/8:错误处理时不关心具体错误类型的下划线:提高代码可读性:猜骰子冷热游戏
讲动人的故事,写懂人的代码 2.6.6 用as进行类型转换:显式而简洁的语法 贾克强:“大家在查看Rust代码时,可能会注意到这一句。在这里,如果我们不使用as i32,编译器会报错,因为它在u32中找不到abs()方法。这是因为prev和sum_of_two_dice都是u32类型,u32类型并不支持abs(…...
大话C语言:第24篇 预处理
1 C语言编译流程 C语言的编译流程包括: 预编译:将.c 中的头文件展开、宏展开,生成的文件是.i 文件。gcc指令:gcc -E file.c -o file.i 编译:将预处理之后的.i 文件生成 .s 汇编文件。gcc指令:gcc -S file…...
React如何配置路由
ReactTs配置路由 安装依赖 npm i react-router-dom在routers下面创建index.tsx import { RouteObject } from react-router-dom import React from react import PageA from /views/PageA import PageB from /views/PageB const routes: RouteObject[] [{path: /,element: …...
MAC使用初体验+入门
之前从来没有使用过MAC,这次拿到了一个 不得不说MAC度过适应期后用起来很舒服,续航长,触控板舒服,轻薄无比 我前期过度的时候记录的一部分快速指南,掌握如下一些电脑常识 可以做到正常使用了 基本操作 在 Mac 上使用桌…...
Go TOKEN机制与跨域处理方式
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…...
JavaScript 的运行
语法分析预编译解释执行 1.语法分析 语法分析是 JavaScript 引擎处理代码的第一步。 在这个阶段,引擎将源代码字符串分解成一个个的词素(token),这些词素是语言中有意义的最小单元,如关键字、变量名、操作符等。 语…...
园区地图导航系统:技术原理、部署方案与智能化应用解析
随着智能化时代的到来,园区管理面临诸多挑战。维小帮园区地图导航系统,采用前沿技术,为园区提供全面的导航解决方案,极大提升了园区管理效率和用户体验。 一、园区地图导航系统的功能特点 维小帮园区地图导航系统,以其…...
【数据结构】第十六弹---C语言实现希尔排序
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】 目录 1、希尔排序( 缩小增量排序 ) 1.1、预排序实现 1.2、希尔排序代码实现 1.3、代码测试 1.4、时空复杂度分析 1.5、性能比较 总结 上一弹我们…...
用Python向Word文档添加页眉和页脚
用Python向Word文档添加页眉和页脚 添加页眉和页脚效果代码 添加页眉和页脚 在本文中,我们将用python向文档中添加页眉和页脚。 效果 添加前的文档: 添加页眉和页脚后: 代码 from docx import Documentdef add_header_footer(doc_path…...
REST风格
黑马程序员Spring Boot2 文章目录 1、REST简介1.1 优点1.2 REST风格简介1.3 注意事项 2、RESTful入门案例 1、REST简介 1.1 优点 隐藏资源的访问行为,无法通过地址的值对资源适合中操作书写简化 1.2 REST风格简介 按照RST风格访问资源时使用行为动作区分对资源进…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
