本节是《Java数据结构及算法实战》系列的第3节,主要介绍程序性能的两种表示方式。
评价一个程序好坏的指标非常多,比如易用性、稳定性、可维护性等等,但一个最为重要的评价指标是性能。性能是其他评价指标的基础。
比如,在Web网站响应时间方面,业界的评判标准是主样的:
- 在2秒之内给客户响应被用户认为是“非常有吸引力”的用户体验。
- 在5秒之内给客户响应被用户认为是“比较不错”的用户体验。
- 在10秒之内给客户响应被用户认为是“糟糕”的用户体验。
- 如果超过10秒还没有得到响应,那么大多数用户会认为这次请求是失败的。
由此我们可以得出结论,Web网站的性能越好,处理时间越短,响应时间越短,则会有更好的用户体验。
所谓程序性能(Program Performance),是指运行一个程序所需要的内存大小和时间。有两个专业的术语来代表程序在运行时所要占用的内存大小和时间,那就是空间复杂度和时间复杂度。
1. 空间复杂度
程序的空间复杂度(Space Complexity)是指运行完一个程序所需要的内存大小。对一个程序的空间复杂度感兴趣的主要原因如下:
- 如果程序将要运行在一个多用户计算机系统中,可能需要指明分配给该程序的内存大小。
- 对任何一个计算机系统,想提前知道是否有足够可用的内存来运行该程序。
- 一个问题可能有若干个内存需求各不相同的解决方案。比如,对于某类应用程序有两个不同的版本,这两个版本分别回占用的内存空间为1G和2G不同的版本,占用内存越大运行速度越快。如果当前的计算机少于2G的内存,则只能选择1G的版本。如果计算机大于2G的内存,则只可选择2G的版本。
- 可以利用空间复杂度来估算一个程序所能解决的问题的最大规模。例如,在“学生信息管理系统”中,一个Student类型的对象可能占用1K字节的内存。当可利用的内存总量为1024K字节,那么最大可以处理1024个学生的信息。
2. 时间复杂度
程序的时间复杂度(Time Complexity)是指运行完该程序所需要的时间。需要关注程序的时间复杂度的原因有以下几点:
- 有些系统需要用户提供运行时间的上限,一旦达到这个上限,客户端程序将被强制结束。比如,数据库的客户端连接会话往往会设置一个超时时间,当客户端的执行时间大于会话的超时时间时,该会话会被终止。这种办法可以避免某个客户端长时间占用系统资源而导致整个系统不可用。
- 交互式程序往往要求实时响应。比如,访问Web网站,用户总是期望网页能够及时响应。
- 如果一个问题有多种解决方案,那么具体采用哪种方案,主要根据这些方案的性能差异。对于各种方案的时间和空间的性能,需要权衡考虑。比如,在一个实时性要求比较高的场景下,往往会将经常访问的数据缓存在内存中(比如Redis),从而提升查询的效率,这就是一个典型的牺牲空间性能换取时间性能的场景。
简言之,空间复杂度和时间复杂度越小的程序,其性能越高。如果空间复杂度和时间复杂度两者不可兼得,则需要权衡。
参考引用
- 本系列归档
- 数据结构和算法基础(Java语言实现)