经过几个月的忙碌,我厂最近的电商平台项目终于上线,期间遇到的问题以及解决方案,也可以拿来和大家多做交流了。

我厂的项目大多采用C#.net,使用逐渐发展并流行起来的EF(Entity Framework)框架,并搭配使用丹麦的一款主打CMS, DMS的.net web应用程序sitecore。

本篇为基础篇,侧重于阐述编码规范和一些编码技巧对系统性能的影响。不规范的编码方式,可能对单个方法或模块产生的性能影响是微不足道的,但在大型电商项目中,高并发的场景随处可见,欠妥的编码方式,可能会对整个系统的性能及用户体验,造成很大的影响。

作为电商项目,对性能影响最明显的模块,莫过于下订单及修改库存。在高并发场景下,这些模块的数据库存取的性能要求是非常高的,少许的性能浪费,都可能使系统在使用中的表现差强人意。

首先,我们来阐述一下EF框架下得编码规范。这里我们可以参考msdn关于IQueryable<T>及IEnumerable<T>的介绍:

对于在内存中集合上运行的方法(即扩展 IEnumerable< T> 的那些方法),返回的可枚举对象将捕获传递到方法的参数。在枚举该对象时,将使用查询运算符的逻辑,并返回查询结果。

与之相反,扩展 IQueryable <T> 的方法不会实现任何查询行为,但会生成一个表示要执行的查询的表达式树。查询处理由源 IQueryable<T> 对象处理。

IQueryable<T>会生成一个查询表达式树,并不会将数据直接取出来,但该对象的扩展方法为我们提供了大量的高效辅助功能,例如判断数据是否存在的Any(),查询数据数量的Count(),统计计数属性的Sum()等,EF会帮助我们生成最优的sql,以减少数据库存取时的性能损耗。这些方法,我们都可以用比较笨拙的编码方式进行实现,但其效率会低很多。

另外,编码过程中应尽可能避免使用ToList()方法及GetById()方法,这里依旧可以参考msdn,但笔者可以直白地去描述:采用这两种方法后,程序会直接将数据从数据库中读取出来,并加载到内存,接下来我们可以直接操作这些实实在在的数据,并使用List<T>所扩展的方法。然而这种方案会造成以下性能问题:

1.将未经业务处理的表达式树直接用来查询数据,其数据量太大,数据库的存取,磁盘的IO,都需要消耗大量的时间和空间。

2.EF支持的导航属性,会将相关联的对象都查出来,届时庞大的数据又拥有更庞大的分支,让内存和CPU飙升。

为了避免上述问题,EF为我们提供了行之有效的方法:

1.查询初期少用ToList()及GetDtoById()方法。

2.查询过程中,使用Select()和SelectMany()方法,只选取自己所需要的属性或对象。

为了看出不规范的编码方式带来的性能损耗,我们来看一段例子比较:

1.以下是只选取自己所需的属性的代码:

var productSKU = unitOfWork.ProductSku.Get(p => p.Id == item.SKUId)
  .Select(p => new { p.Id, p.ProductId, p.Product })
  .FirstOrDefault();

提交订单耗时的截图:

2.采用GetById()方法:

var productSKU = unitOfWork.ProductSku.GetByID(item.SKUId);

提交订单耗时截图:

笔者电脑老旧,该数据在i5 8G ram的计算机中仅需要200ms的时长,在性能更强的服务器上耗时更短。

从对比中我们可以看到:仅仅只修改了一个方法,程序请求的耗时竟有将近一倍的误差!如果我们的代码中充斥着这种懒惰的不规范写法,在高并发场景下,系统会被拖得很慢,甚至会出现程序报错。

接下来,我们说下抛开EF框架的做法,擅长sql编程的园友,可能会不屑EF的提供的各种方案,直接写sql,采用ADO不是更快吗?的确,直接运行sql会让程序更快,ADO的速度是大家所认可的。EF也支持大家使用直接编写sql的方式:

var productSKU = dbContext.Database.SqlQuery<ProductSku>(sqlStr);

如果sql编程功力深厚,笔者是非常支持这种编程方案的。但EF框架也有其天生的优势:

1.EF框架让更多的初级软件从业者更快地学习和编写程序

2.EF提供的完善的扩展方法,帮助软件从业人员实现各种功能

3.规范编写的EF C#代码,并不会比原生的sql慢太多

这让笔者想起C#.net与Java程序员之间的矛盾^_^。笔者因为机缘巧合,也写过一段时间的Java。

二者的设计理念确实有所不同:

1.C#.net让初学者更快地入门,提供了更多的类库和方法,其出色的IDE让编程人员省心省力。且C#.net已经开源。

2.Java则需要编程人员做更多的思考,自己配置环境变量,自己敲命令行,让编程人员在思考的过程中加深对计算机原理、操作系统和软件工程的认识。

毫无疑问:两者都是当代最出色的高级程序语言(PHP,Python,JavaScript等的同行勿喷^_^)与其花时间争论谁才是最好的语言,不如兼而学之。

以上是本次性能优化介绍的基础篇,后续会为大家带来数据库层面的优化经验及体会。

C# 大型电商项目性能优化(一)的更多相关文章

  1. Java开源生鲜电商平台-性能优化以及服务器优化的设计与架构(源码可下载)

    Java开源生鲜电商平台-性能优化以及服务器优化的设计与架构(源码可下载) 说明:Java开源生鲜电商平台-性能优化以及服务器优化的设计与架构,我采用以下三种维度来讲解 1.  代码层面. 2.  数 ...

  2. Spark大型电商项目实战-及其改良之番外(1)-将spark前端页面效果高效拷贝至博客

    Spark大型电商项目实战-及其改良这个系列的时间轴展示图一直在变....1-3篇是用图直接表示时间轴,用一段简陋的html代码表示时间表.第4篇开始才是用比较完整的前端效果,能移动.缩放时间轴,鼠标 ...

  3. C#大型电商项目优化(二)——嫌弃EF与抛弃EF

    上一篇博文中讲述了使用EF开发电商项目的代码基础篇,提到EF后,一语激起千层浪.不少园友纷纷表示:EF不适合增长速度飞快的互联网项目,EF只适合企业级应用等等. 也有部分高手提到了分布式,确实,性能优 ...

  4. vue大型电商项目尚品汇(前台篇)day01

    学完vue2还是决定先做一个比较经典,也比较大的项目来练练手好一点,vue3的知识不用那么着急,先把vue2用熟练了,vue3随时都能学. 这个项目确实很经典包含了登录注册.购物车电商网站该有的都有, ...

  5. Spark大型电商项目实战-及其改良(3) 分析sparkSQL语句的性能影响

    之前的运行数据被清除了,只能再运行一次,对比一下sparkSQL语句的影响 纯SQL的时间 对应时间表 th:first-child,.table-bordered tbody:first-child ...

  6. Spark大型电商项目实战-及其改良(2) RDD优化效果不稳定的真正原因

    首先看没有map join的第2任务: 时间线如下 接着是对应id的算子计算时间表 Stage Id Description Submitted Duration Tasks: Succeeded/T ...

  7. C#大型电商项目优化(三)——扩展性与支付

    上一篇文章引来不少非议,笔者并非对EF有看法,而是针对不同的业务场景和框架背景,挑选不同的方案.每个方案都有其优势劣势,挑选最快速,最简单的方案,是笔者的初衷. 看评论也是学习的过程,然而有些只做评价 ...

  8. Spark大型电商项目实战-及其改良(1) 比对sparkSQL和纯RDD实现的结果

    代码存在码云:https://coding.net/u/funcfans/p/sparkProject/git 代码主要学习https://blog.csdn.net/u012318074/artic ...

  9. vue大型电商项目尚品汇(前台篇)day02

    现在正式回归,开始好好做项目了,正好这一个项目也开始慢慢的开始起色了,前面的准备工作都做的差不多了. 而且我现在也开始慢慢了解到了一些项目才开始需要的一些什么东西了,vuex.router这些都是必备 ...

随机推荐

  1. VMware虚拟机安装教程详解图文

            学习Linux系统最好的方式就是在自己的虚拟机上安装Linux:接下来就给大家简单介绍一下VMware虚拟机的安装以及Linux的安装:VMware虚拟机只是为了更好的学习Linux: ...

  2. 国内常用的几个NTP时间服务器

    问题描述: 经常Windows或者Linux系统上面的时间跟我们本地的时间不一致 有时候就是Windows的Internet时间设置里面的Windows自带的时间同步服务器不好使 Linux配置NTP ...

  3. 1.1 机中容量单位B、KB、MB、GB和TB的关系

    字节(Byte,简称B)与K.KB.M.MB的关系 1.计算机中各种存储容量的单位都是用字节(Byte简为B)来表示,此外还有KB.MB.GB和TB,他们的关系是: 1KB=1024Bytes=2的1 ...

  4. synchronized 的局限性 与 Lock 的优点

    我们已经知道,synchronized 是Java的关键字,是Java的内置特性,在JVM层面实现了对临界资源的同步互斥访问,但 synchronized 粒度有些大,在处理实际问题时存在诸多局限性, ...

  5. 难点--均方误差(MSE)和均方根误差(RMSE)和平均绝对误差(MAE)

    MSE: Mean Squared Error 均方误差是指参数估计值与参数真值之差平方的期望值; MSE可以评价数据的变化程度,MSE的值越小,说明预测模型描述实验数据具有更好的精确度. MSE=1 ...

  6. 【Java多线程】ReentrantReadWriteLock

    概述 ReentrantReadWriteLock是Lock的另一种实现方式,ReentrantLock是一个排他锁,同一时间只允许一个线程访问,而ReentrantReadWriteLock允许多个 ...

  7. [BJWC2011]元素

    嘟嘟嘟 题中说选的数的编号亦或和不能为0,也就是在这个集合中,不能用不同的选取方案亦或出相同的值.由此联想到线性基的一个性质是,每一个数都能由线性基中特定的一些数亦或得到. 所以我们就是要求出这些数的 ...

  8. 【转】避免全表扫描的sql优化

    对查询进行优化,应尽量避免全表扫描,首先应考虑在where 及order by 涉及的列上建立索引: .尝试下面的技巧以避免优化器错选了表扫描:· 使用ANALYZE TABLE tbl_name为扫 ...

  9. Blinker 后台数据分析

    如何解析出后台服务器认证信息,供自己的设备连接. 测试程序 天气 增加了 Debug输出信息功能 1手机APP添加控件信息   2硬件烧录程序 #define BLINKER_PRINT Serial ...

  10. 课程设计小组报告——基于ARM实验箱的捕鱼游戏的设计与实现

    课程设计小组报告--基于ARM实验箱的捕鱼游戏的设计与实现 一.任务简介 1.1 任务内容 捕鱼游戏这个项目是一个娱乐性的游戏开发,该游戏可以给人们带来娱乐的同时还可以给人感官上的享受,所以很受人们的 ...