基于Python的简单40例和爬虫详细讲解(文末赠书)

目录


随着人工智能以及大数据的兴起,学习Python的人也是越来越多。PYTHON语法清晰明快,简单易学。这是Python如此普及的重要原因。但是,选择合适的Python学习方式,需要跟你自身的特性相结合。而且学习本来就是一件非常煎熬的事情,坚持永远是普通人面临的最大问题。接下来就来和大家聊聊python经典编程40例

先来看看Python40例

1 十转二

将十进制转换为二进制:

1

2

3

>>> bin(10)

'0b1010'

2 十转八

十进制转换为八进制:

1

2

3

>>> oct(9)

'0o11'

3 十转手六

十进制转换为十六进制:

1

2

3

>>> hex(15)

'0xf'

4 字符串转字节

字符串转换为字节类型

1

2

3

4

5

>>> s = "apple"

>>> bytes(s,encoding='utf-8')

b'apple'

5 转为字符串

字符类型、数值型等转换为字符串类型

1

2

3

4

5

>>> i = 100

>>> str(i)

'100'

6 十转ASCII

十进制整数对应的 ASCII 字符

1

2

3

>>> chr(65)

'A'

7 ASCII转十

ASCII字符对应的十进制数

1

2

3

>>> ord('A')

65

8 转为字典

创建数据字典的几种方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

>>> dict()

{}

>>> dict(a='a',b='b')

{ 'a': 'a', 'b': 'b'}

>>> dict(zip(['a','b'],[1,2]))

{ 'a': 1, 'b': 2}

>>> dict([('a',1),('b',2)])

{ 'a': 1, 'b': 2}

9 转为浮点类型

整数或数值型字符串转换为浮点数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

>>> float(3)

3.0

如果不能转化为浮点数,则会报ValueError:

>>> float('a')

Traceback (most recent call last):

File "<pyshell#7>", line 1, in <module>

float('a')

ValueError: could not convert string to float: 'a'

10 转为整型

int(x, base =10)

x 可能为字符串或数值,将 x 转换为整数。

如果参数是字符串,那么它可能包含符号和小数点。如果超出普通整数的表示范围,一个长整数被返回。

1

2

3

>>> int('12',16)

18

11 转为集合

返回一个 set 对象,集合内不允许有重复元素:

1

2

3

4

5

>>> a = [1,4,2,3,1]

>>> set(a)

{1, 2, 3, 4}

12 转为切片

class slice(start, stop[, step])

返回一个由 range(start, stop, step) 指定索引集的 slice 对象,代码可读性变好。

1

2

3

4

5

6

7

>>> a = [1,4,2,3,1]

>>> my_slice = slice(0,5,2)

>>> a[my_slice]

[1, 2, 1]

13 转元组

tuple() 将对象转为一个不可变的序列类型

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

>>> a=[1,3,5]

>>> a.append(7)

>>> a

[1, 3, 5, 7]

#禁止a增删元素,只需转为元组

>>> t=tuple(a)

>>> t

(1, 3, 5, 7)

14 转冻结集合

创建不可修改的集合:

1

2

3

4

5

>>> a = frozenset([1,1,3,2,3])

>>> a # a 无 pop,append,insert等方法

frozenset({1, 2, 3})

15 商和余数

分别取商和余数

1

2

3

>>> divmod(10,3)

(3, 1)

16 幂和余同时做

pow 三个参数都给出表示先幂运算再取余:

>>> pow(3, 2, 4)

17 四舍五入

四舍五入,ndigits代表小数点后保留几位:

1

2

3

4

5

6

7

>>> round(10.045, 2)

10.04

>>> round(10.046, 2)

10.05

18 查看变量所占字节数

1

2

3

4

5

6

7

>>> import sys

>>> a = { 'a':1,'b':2.0}

>>> sys.getsizeof(a) # 变量占用字节数

240

19 门牌号

返回对象的内存地址

1

2

3

4

5

6

7

8

9

10

11

12

13

>>> class Student():

def __init__(self,id,name):

self.id = id

self.name = name

>>> xiaoming = Student('001','xiaoming')

>>> id(xiaoming)

2281930739080

20 排序函数

排序:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

>>> a = [1,4,2,3,1]

#降序

>>> sorted(a,reverse=True)

[4, 3, 2, 1, 1]

>>> a = [{ 'name':'xiaoming','age':18,'gender':'male'},

{ 'name':'xiaohong','age':20,'gender':'female'}]

#按 age升序

>>> sorted(a,key=lambda x: x['age'],reverse=False)

[{ 'name': 'xiaoming', 'age': 18, 'gender': 'male'},

{ 'name': 'xiaohong', 'age': 20, 'gender': 'female'}]

21 求和函数

求和:

1

2

3

4

5

6

7

8

9

10

11

>>> a = [1,4,2,3,1]

>>> sum(a)

11

#求和初始值为1

>>> sum(a,1)

12

22 计算表达式

计算字符串型表达式的值

1

2

3

4

5

6

7

>>> s = "1 + 3 +5"

>>> eval(s)

>>> eval('[1,3,5]*3')

[1, 3, 5, 1, 3, 5, 1, 3, 5]

23 真假

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

>>> bool(0)

False

>>> bool(False)

False

>>> bool(None)

False

>>> bool([])

False

>>> bool([False])

True

>>> bool([0,0,0])

True

24 都为真

如果可迭代对象的所有元素都为真,那么返回 True,否则返回False

1

2

3

4

5

6

7

8

9

10

11

#有0,所以不是所有元素都为真

>>> all([1,0,3,6])

False

#所有元素都为真

>>> all([1,2,3])

True

25 至少一个为真

接受一个可迭代对象,如果可迭代对象里至少有一个元素为真,那么返回True,否则返回False

1

2

3

4

5

6

7

8

9

10

11

# 没有一个元素为真

>>> any([0,0,0,[]])

False

# 至少一个元素为真

>>> any([0,0,1])

True

26 获取用户输入

获取用户输入内容

1

2

3

4

5

>>> input()

I'm typing

"I'm typing "

27 print 用法

1

2

3

4

5

6

7

8

9

10

11

12

13

>>> lst = [1,3,5]

# f 打印

>>> print(f'lst: {lst}')

lst: [1, 3, 5]

# format 打印

>>> print('lst:{}'.format(lst))

lst:[1, 3, 5]

28 字符串格式化

格式化字符串常见用法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

>>> print("i am {0},age {1}".format("tom",18))

i am tom,age 18

>>> print("{:.2f}".format(3.1415926)) # 保留小数点后两位

3.14

>>> print("{:+.2f}".format(-1)) # 带符号保留小数点后两位

-1.00

>>> print("{:.0f}".format(2.718)) # 不带小数位

>>> print("{:0>3d}".format(5)) # 整数补零,填充左边, 宽度为3

005

>>> print("{:,}".format(10241024)) # 以逗号分隔的数字格式

10,241,024

>>> print("{:.2%}".format(0.718)) # 百分比格式

71.80%

>>> print("{:.2e}".format(10241024)) # 指数记法

1.02e+07

29 返回对象哈希值

返回对象的哈希值。值得注意,自定义的实例都可哈希:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

>>> class Student():

def __init__(self,id,name):

self.id = id

self.name = name

>>> xiaoming = Student('001','xiaoming')

>>> hash(xiaoming)

-9223371894234104688

list, dict, set等可变对象都不可哈希(unhashable):

>>> hash([1,3,5])

Traceback (most recent call last):

File "<pyshell#71>", line 1, in <module>

hash([1,3,5])

TypeError: unhashable type: 'list'

30 打开文件

返回文件对象

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

>>> import os

>>> os.chdir('D:/source/dataset')

>>> os.listdir()

['drinksbycountry.csv', 'IMDB-Movie-Data.csv', 'movietweetings',

'titanic_eda_data.csv', 'titanic_train_data.csv']

>>> o = open('drinksbycountry.csv',mode='r',encoding='utf-8')

>>> o.read()

"country,beer_servings,spirit_servings,wine_servings,total_litres_of_pur

e_alcohol,continent\nAfghanistan,0,0,0,0.0,Asia\nAlbania,89,132,54,4.9,"

mode 取值表:

字符意义’r’读取(默认)’w’写入,并先截断文件’x’排它性创建,如果文件已存在则失败’a’写入,如果文件存在则在末尾追加’b’二进制模式’t’文本模式(默认)’+’打开用于更新(读取与写入)

31 查看对象类型

class type(name, bases, dict)

传入参数,返回 object 类型:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

>>> type({4,6,1})

<class 'set'>

>>> type({ 'a':[1,2,3],'b':[4,5,6]})

<class 'dict'>

>>> class Student():

def __init__(self,id,name):

self.id = id

self.name = name

>>> type(Student('1','xiaoming'))

<class '__main__.Student'>

32 两种创建属性方法

返回 property 属性,典型的用法:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

>>> class C:

def __init__(self):

self._x = None

def getx(self):

return self._x

def setx(self, value):

self._x = value

def delx(self):

del self._x

# 使用property类创建 property 属性

x = property(getx, setx, delx, "I'm the 'x' property.")

使用 C 类:

>>> C().x=1

>>> c=C()

# 属性x赋值

>>> c.x=1

# 拿值

>>> c.getx()

# 删除属性x

>>> c.delx()

# 再拿报错

>>> c.getx()

Traceback (most recent call last):

File "<pyshell#118>", line 1, in <module>

c.getx()

File "<pyshell#112>", line 5, in getx

return self._x

AttributeError: 'C' object has no attribute '_x'

# 再属性赋值

>>> c.x=1

>>> c.setx(1)

>>> c.getx()

使用@property装饰器,实现与上完全一样的效果:

class C:

def __init__(self):

self._x = None

@property

def x(self):

return self._x

@x.setter

def x(self, value):

self._x = value

@x.deleter

def x(self):

del self._x

33 是否可调用

判断对象是否可被调用,能被调用的对象是一个callable 对象。

1

2

3

4

5

6

7

>>> callable(str)

True

>>> callable(int)

True

Student 对象实例目前不可调用:

1

2

3

4

5

6

7

8

9

10

11

12

13

>>> class Student():

def __init__(self,id,name):

self.id = id

self.name = name

>>> xiaoming = Student(id='1',name='xiaoming')

>>> callable(xiaoming)

False

如果 xiaoming能被调用 , 需要重写Student类的__call__方法:

1

2

3

4

5

6

7

>>> class Student():

def __init__(self,id,name):

self.id = id

self.name = name

此时调用 xiaoming():

1

2

3

4

5

6

7

>>> xiaoming = Student('001','xiaoming')

>>> xiaoming()

I can be called

my name is xiaoming

34 动态删除属性

删除对象的属性

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

>>> class Student():

def __init__(self,id,name):

self.id = id

self.name = name

>>> xiaoming = Student('001','xiaoming')

>>> delattr(xiaoming,'id')

>>> hasattr(xiaoming,'id')

False

35 动态获取对象属性

获取对象的属性

1

2

3

4

5

6

7

8

9

10

11

12

13

>>> class Student():

def __init__(self,id,name):

self.id = id

self.name = name

>>> xiaoming = Student('001','xiaoming')

>>> getattr(xiaoming,'name') # 获取name的属性值

'xiaoming'

36 对象是否有某个属性

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

>>> class Student():

def __init__(self,id,name):

self.id = id

self.name = name

>>> xiaoming = Student('001','xiaoming')

>>> getattr(xiaoming,'name')# 判断 xiaoming有无 name属性

'xiaoming'

>>> hasattr(xiaoming,'name')

True

>>> hasattr(xiaoming,'address')

False

37 isinstance

判断object是否为classinfo的实例,是返回true

1

2

3

4

5

6

7

8

9

10

11

12

13

>>> class Student():

def __init__(self,id,name):

self.id = id

self.name = name

>>> xiaoming = Student('001','xiaoming')

>>> isinstance(xiaoming,Student)

True

38 父子关系鉴定

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

>>> class Student():

def __init__(self,id,name):

self.id = id

self.name = name

>>> class Undergraduate(Student):

pass

# 判断 Undergraduate 类是否为 Student 的子类

>>> issubclass(Undergraduate,Student)

True

第二个参数可为元组:

>>> issubclass(int,(int,float))

True

39 所有对象之根

object 是所有类的基类

1

2

3

4

5

6

7

>>> isinstance(1,object)

True

>>> isinstance([],object)

True

40 一的查看对象所有方法

不带参数时返回当前范围内的变量、方法和定义的类型列表;带参数时返回参数的属性,方法列表。

1

2

3

4

5

6

7

8

9

10

11

12

13

>>> class Student():

def __init__(self,id,name):

self.id = id

self.name = name

>>> xiaoming = Student('001','xiaoming')

>>> dir(xiaoming)

['__call__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'id', 'name']

学习Python容易坐牢?

 介绍一下什么是爬虫

1、收集数据

python爬虫程序可用于收集数据。这也是最直接和最常用的方法。由于爬虫程序是一个程序,程序运行得非常快,不会因为重复的事情而感到疲倦,因此使用爬虫程序获取大量数据变得非常简单和快速。

由于99%以上的网站是基于模板开发的,使用模板可以快速生成大量布局相同、内容不同的页面。因此,只要为一个页面开发了爬虫程序,爬虫程序也可以对基于同一模板生成的不同页面进行爬取内容。

2、爬虫调研

比如要调研一家电商公司,想知道他们的商品销售情况。这家公司声称每月销售额达数亿元。如果你使用爬虫来抓取公司网站上所有产品的销售情况,那么你就可以计算出公司的实际总销售额。此外,如果你抓取所有的评论并对其进行分析,你还可以发现网站是否出现了刷单的情况。数据是不会说谎的,特别是海量的数据,人工造假总是会与自然产生的不同。过去,用大量的数据来收集数据是非常困难的,但是现在在爬虫的帮助下,许多欺骗行为会赤裸裸地暴露在阳光下。

3、刷流量和秒杀

刷流量是python爬虫的自带的功能。当一个爬虫访问一个网站时,如果爬虫隐藏得很好,网站无法识别访问来自爬虫,那么它将被视为正常访问。结果,爬虫“不小心”刷了网站的流量。

除了刷流量外,还可以参与各种秒杀活动,包括但不限于在各种电商网站上抢商品,优惠券,抢机票和火车票。目前,网络上很多人专门使用爬虫来参与各种活动并从中赚钱。这种行为一般称为“薅羊毛”,这种人被称为“羊毛党”。不过使用爬虫来“薅羊毛”进行盈利的行为实际上游走在法律的灰色地带,希望大家不要尝试。

二、爬虫是如何工作的?

原则上,爬虫就像图书馆员。它在 Web 上查找分配给某些类别的信息,然后对其进行索引和编目,以便可以检索和评估已爬网的信息。‎

‎在启动爬网之前,需要建立这些计算机程序的操作。因此,每个订单都是预先定义的。然后,爬网程序会自动执行这些指令。使用爬网程序的结果创建索引,可以通过输出软件访问该索引。‎

‎爬网程序将从 Web 收集的信息取决于特定的指令。‎

三、爬虫与SEO优化

像Googlebot这样的网络爬虫通过抓取和索引来实现他们在‎‎SERP‎‎中对网站进行排名的目的。他们遵循WWW和网站上的永久链接。每个网站,每个爬虫都有有限的时间范围和‎‎预算‎‎可用。网站所有者可以通过优化网站结构(如导航)来更有效地利用Googlebot的抓取预算。由于会话数量较多且可信赖的传入链接而被认为更重要的 URL 通常会被更频繁地抓取。有一些措施可以控制Googlebot(如机器人.txt)和XML站点地图等抓取工具(例如机器人),这些工具可以提供不抓取网站某些区域的具体说明。它存储在‎‎Google搜索控制台中,‎‎并提供网站结构的清晰概述,使其清楚地了解应抓取哪些区域并将其编入索引。‎

什么是python爬虫

Python爬虫即使用Python程序开发的网络爬虫(网页蜘蛛,网络机器人),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。爬虫指一段自动抓取互联网信息的程序,从互联网上抓取对于我们有价值的信息。

Python爬虫架构

Python 爬虫架构主要由五个部分组成:

  • 调度器:相当于一台电脑的CPU,主要负责调度URL管理器、下载器、解析器之间的协调工作。
  • URL管理器:包括待爬取的URL地址和已爬取的URL地址,防止重复抓取URL和循环抓取URL,实现URL管理器主要用三种方式,通过内存、数据库、缓存数据库来实现。
  • 网页下载器:通过传入一个URL地址来下载网页,将网页转换成一个字符串,网页下载器有urllib2(Python官方基础模块)包括需要登录、代理、和cookie,requests(第三方包)
  • 网页解析器:将一个网页字符串进行解析,可以按照我们的要求来提取出我们有用的信息,也可以根据DOM树的解析方式来解析。网页解析器有正则表达式(直观,将网页转成字符串通过模糊匹配的方式来提取有价值的信息,当文档比较复杂的时候,该方法提取数据的时候就会非常的困难)、html.parser(Python自带的)、beautifulsoup(第三方插件,可以使用Python自带的html.parser进行解析,也可以使用lxml进行解析,相对于其他几种来说要强大一些)、lxml(第三方插件,可以解析 xml 和 HTML),html.parser 和 beautifulsoup 以及 lxml 都是以 DOM 树的方式进行解析的。
  • 应用程序:就是从网页中提取的有用数据组成的一个应用。

最担心的问题

都说学爬虫就一定会坐牢,这个说法是错误的。

01.技术无罪?

很多朋友给我留言:技术是无罪的,技术本身确实是没有对错的,但使用技术的人是有对错的,公司或者程序员如果明知使用其技术是非法的,那么公司或者人就需要为之付出代价。

在今年国家颁布**《中华人民共和国网络安全法》**之后,很多以前处于灰色地带的业务都不能做了。

君不见之前曾经非常火的各种社工库网站,现在绝大部分都已经消失匿迹了吗?因为最新的安全法强调:贩卖个人信息超过50条属于“情节严重”,需要追求其法律责任。

很多草根站长都纷纷主动关闭了网站;还有很多涉及版权信息的网站,比如书籍、影视剧、课程等后期也会面临越来越严格的审查,这就是目前大的形势。

2014年12月20日,人人影视字幕站发布微博称,人人影视正式关闭,并表示或将继续为正版商提供翻译服务,也可能转变为讨论社区的形式。

2019年6月,吾爱破解因版权问题关站整改…

随着中国经济的不断往前走,知识产权问题会越来越重视,非法爬虫是现在一个重要的打击部分,

如果有程序员走在灰色的边缘尽早收手,不要因为一点小的收益导致触犯法律,从而得不偿失。

技术是无罪的,但是用到了错的地方代价也是非常巨大的。

爬取网上公开信息不犯法,但如果大量开启爬虫导致对方服务器崩溃也是违法的,这属于暴力攻击的范畴了。

写了一段代码上传到 Github 上面,有人利用你的代码做了其它非法的事情,绝大多数都没有问题的,但如果你写的软件涉及到入侵、暴力破解、病毒等就不好说了。

还有朋友认为这事责任在企业不在程序员,日常工作中项目初期设计和最后上线需要通过公司的法务批准,所有代码必须有其他程序员同事评审通过才能提交。

这位朋友说的挺对的,按道理每个公司都应该有法务和风控在前面,后面才是产品设计和程序员开发的事情,但如果一家公司为了利益,老板可以直接让这两个部门闭嘴,后面程序员可以不干吗?

更甚至很多公司其实就没有这两个部门或者说形同虚设。那么做为程序员自己也需要操一份心,凡是涉及到入侵类的程序都不能干,因为有一个东西叫做:单位犯罪

单位犯罪,是指公司、企业、事业单位、机关、团体为单位谋取利益,经单位决策机构或者负责人决定实施的,法律规定应当负刑事责任的危害社会的行为。

我国刑法对单位犯罪原则上采取双罚制度,即单位犯罪的,对单位判处罚金,并对其直接负责的主管人员和其他直接责任人员判处刑罚

例子:

import os
import requests
from bs4 import BeautifulSoup
 
 
headers={
        'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
    }
url="https://www.test.com/chaxun/zuozhe/77.html"
 
 
def getPoems():
    res= requests.get(url=url,headers=headers)
    res.encoding='UTF-8'
    page_text=res.text
    #在首页解析出章节
    soup = BeautifulSoup(page_text,'lxml')
    shici_list = soup.select(".shici_list_main > h3 > a")
    shici_name=[]
    for li in shici_list:
        data_url = "https://www.test.com"+li['href']
        # print(li.string+"======="+data_url)
        shici_name.append(li.string)
        detail_res = requests.get(url=data_url,headers=headers)
        detail_res.encoding='UTF-8'
        detail_page_text=detail_res.text
        detail_soup = BeautifulSoup(detail_page_text,'lxml')
        detail_content = detail_soup.find("div",class_="item_content").text
        # print(detail_content)
        with open("./shici.txt",'a+',encoding= 'utf8') as file:
            if shici_name.count(li.string)==1:
                file.write(li.string)
            file.write(detail_content+"\n")
            print(li.string+"下载完成!!!!")     
        
 
if __name__=="__main__":
    getPoems()

本期送书

获取方式:收藏·点赞·评论就有机会获得

获取方式:1.评论赞数最高一位即可获得

                  2.随机抽取一位高质量评论的朋友赠书一本!!

截止时间:4月20日晚上7:00

 

《C++高性能编程》适用于从事性能关键项目开发并希望学习不同技术以提高代码性能的经验丰富的开发人员和程序员。计算机建模、算法交易、游戏、生物信息学、基于物理的模拟、计算机辅助设计、计算基因组学或计算流体动力学等领域的程序员都可以从本书中学习到各种技术,并将之应用到自己的工作领域。

本书详细阐述了与C++高性能编程相关的基本解决方案,主要包括性能和并发性简介,性能测量,CPU架构、资源和性能,内存架构和性能,线程、内存和并发,并发和性能,并发数据结构,C++中的并发,高性能C++,C++中的编译器优化,未定义行为和性能,性能设计等内容。此外,本书还提供了相应的示例、代码,以帮助读者进一步理解相关方案的实现过程。本书适合作为高等院校计算机及相关专业的教材和教学参考书,也可作为相关开发人员的自学用书和参考手册。

目录

第1篇性能基础
第1章性能和并发性简介3
1.1程序员要关注性能的原因3
1.2有关性能重要性的解释6
1.3程序性能8
1.3.1吞吐量指标8
1.3.2功耗指标9
1.3.3实时应用性能10
1.3.4上下文环境11
1.4评估和预测性能12
1.5精通高性能应用程序开发13
1.6小结14
1.7思考题15
第2章性能测量17
2.1技术要求17
2.2性能测量示例18
2.3性能基准测试25
2.3.1C++计时器25
2.3.2高分辨率计时器26
2.4性能分析31
2.4.1perf性能分析器32
2.4.2使用perf进行详细性能分析34
2.4.3GooglePerformance性能分析器37
2.4.4使用调用图进行性能分析38
2.4.5优化和内联42
2.4.6实际性能分析44
2.5微基准测试45
2.5.1微基准测试的基础知识45
2.5.2微基准测试和编译器优化48
2.5.3GoogleBenchmark51
2.5.4微基准测试是谎言54
2.6小结58
2.7思考题59
第3章CPU架构、资源和性能61
3.1技术要求61
3.2CPU和性能62
3.3使用微基准测试性能64
3.4可视化指令级并行性70
3.5数据依赖和流水线72
3.6流水线和分支77
3.6.1分支预测80
3.6.2分支预测错误的性能分析82
3.7推测执行85
3.8复杂条件的优化86
3.9无分支计算90
3.9.1循环展开90
3.9.2无分支选择91
3.9.3无分支计算示例93
3.10小结96
3.11思考题97
第4章内存架构和性能99
4.1技术要求99
4.2影响性能的不止CPU100
4.3测量内存访问速度102
4.3.1内存架构103
4.3.2测量内存和缓存速度105
4.4内存的速度:数字108
4.4.1随机内存访问速度108
4.4.2顺序内存访问速度111
4.4.3硬件中的内存性能优化113
4.5优化内存性能115
4.5.1高效使用内存的数据结构116
4.5.2分析内存性能119
4.5.3优化内存性能的算法121
4.6机器里的“幽灵”126
4.6.1关于Spectre127
4.6.2Spectre攻击示例129
4.6.3释放“幽灵”133
4.7小结137
4.8思考题137
第5章线程、内存和并发139
5.1技术要求139
5.2理解线程和并发139
5.2.1关于线程140
5.2.2对称多线程141
5.2.3线程和内存141
5.2.4内存受限程序和并发145
5.3了解内存同步的成本146
5.4数据共享成本高昂的原因151
5.5了解并发和顺序157
5.5.1顺序的需要157
5.5.2内存顺序和内存屏障159
5.5.3C++中的内存顺序165
5.6内存模型168
5.7小结172
5.8思考题172
第2篇并发的高级应用
第6章并发和性能175
6.1技术要求175
6.2高效使用并发需要的条件176
6.3锁、替代品及其性能177
6.3.1基于锁、无锁和无等待的程序179
6.3.2针对不同问题的不同锁181
6.3.3锁与无锁的真正区别185
6.4并发编程的构建块187
6.4.1并发数据结构的基础知识188
6.4.2计数器和累加器191
6.4.3发布协议196
6.5并发编程的智能指针198
6.5.1发布指针198
6.5.2原子共享指针201
6.6小结204
6.7思考题204
第7章并发数据结构205
7.1技术要求205
7.2关于线程安全数据结构205
7.2.1优选的线程安全性206
7.2.2真正的线程安全性208
7.3线程安全栈208
7.3.1线程安全的接口设计209
7.3.2互斥锁保护的数据结构的性能211
7.3.3不同用途的性能要求213
7.3.4有关栈性能的细节讨论217
7.3.5同步方案的性能估计220
7.3.6无锁栈223
7.4线程安全队列229
7.4.1无锁队列230
7.4.2非顺序一致的数据结构235
7.4.3并发数据结构的内存管理238
7.5线程安全列表240
7.5.1列表的挑战240
7.5.2无锁列表243
7.6小结249
7.7思考题249
第8章C++中的并发251
8.1技术要求251
8.2C++11中的并发支持251
8.3C++17中的并发支持253
8.4C++20中的并发支持256
8.4.1协程的基础知识257
8.4.2协程C++语法261
8.4.3协程示例262
8.5小结268
8.6思考题269
第3篇设计和编写高性能程序
第9章高性能C++273
9.1技术要求273
9.2关于编程语言的效率273
9.3不必要的复制275
9.3.1复制和参数传递275
9.3.2将复制作为一种实现技术277
9.3.3复制以存储数据278
9.3.4复制返回值279
9.3.5使用指针避免复制283
9.3.6避免不必要的复制284
9.4低效的内存管理285
9.4.1不必要的内存分配285
9.4.2并发程序中的内存管理289
9.4.3避免内存碎片290
9.5条件执行的优化293
9.6小结295
9.7思考题296
第10章C++中的编译器优化297
10.1技术要求297
10.2编译器优化代码297
10.2.1有关编译器优化的基础知识298
10.2.2函数内联300
10.2.3编译器真正知道的东西305
10.2.4将运行时信息转换为编译时信息311
10.3小结314
10.4思考题315
第11章未定义行为和性能317
11.1技术要求317
11.2关于未定义行为317
11.3产生未定义行为的缘由320
11.4未定义行为和C++优化321
11.5使用未定义行为进行高效设计330
11.6小结333
11.7思考题334
第12章性能设计335
12.1技术要求335
12.2设计与性能之间的相互作用335
12.3着眼于性能的设计336
12.3.1最小信息原则337
12.3.2优选信息原则338
12.4API设计注意事项344
12.4.1有关并发的API设计344
12.4.2复制和发送数据349
12.5优化数据访问的设计351
12.6性能权衡354
12.6.1接口设计354
12.6.2组件设计355
12.6.3错误和未定义的行为356
12.7做出明智的设计决策357
12.8小结359
12.9思考题359
附录思考题解答361
第1章性能和并发性简介361
第2章性能测量361
第3章CPU架构、资源和性能362
第4章内存架构和性能363
第5章线程、内存和并发364
第6章并发和性能365
第7章并发数据结构365
第8章C++中的并发366
第9章高性能C++367
第10章C++中的编译器优化368
第11章未定义行为和性能369
第12章性能设计369

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2023年4月22日
下一篇 2023年4月22日

相关推荐