前言:
之前的工作已经保证了算法基本上是按照我们想要的方式在运行,第二个重要的问题就是,如何保证算法在需要的时间中完成工作。毕竟用户可没有多少耐心来等待页面刷新的。
测试的方法是使用gperftools来计算每个函数的调用时间,基于每个函数的调用时间,我们就能统计出json串的加载解析上花费了多少时间。其实之前还接触过gprof,不过由于gperftools效果更好,现在使用这个新工具来统计函数运行时间了。
我的github:
我实现的代码全部贴在我的github中,欢迎大家去参观。
https://github.com/YinWenAtBIT
原测试:
测试目的:
除了UCB算法的反馈值之外,我们还需要考虑现在UCB算法初始化的速度,毕竟客户点击刷新之后,我们需要立刻给用户一个反馈。现在的做法是比较累赘的,现在json串中读取出所有的tags与topics,并且建立两个UCB类与两个map来保存所有的数据,再根据客户的反馈值不断地更新。实际上等同于在服务器程序上自行实现了一个数据库。这样会导致效率比较低。
不过如果这样的做法时间是上没有问题,那我们就可以先这样做着。但是如果不行的话,我们就不能再使用json串来保存数据,而更应该使用bitmap来保存了。
测试条件:
主机:本机,intel 4700mq, 8G内存
Json串数量:2万条
时间花费部分:
1. json类相关,主要是Value类与Reader类,分别用来保存于解析Json串。其中Value类中又调用了map,以及string类。
2. Unorderedmap类,主要用来保存key与对应的json串
3. 其他(系统nw,delete以及其他不好归类的开销)
测试结果:
表2:Json串加载速度测试结果
|
总时间 |
Json类 |
String类 |
Map类 |
UNorderedmap |
其他 |
Json行数:2w |
780ms |
390 |
110 |
130 |
40 |
110 |
Json行数:1.8w |
660ms |
290 |
70 |
90 |
10 |
110 |
Json行数:1.6w |
610ms |
330 |
100 |
70 |
20 |
90 |
Json行数:1.4w |
510ms |
190 |
90 |
60 |
0 |
170 |
Json行数:1.2w |
440ms |
250 |
70 |
50 |
0 |
90 |
Json行数:1w |
370ms |
180 |
60 |
40 |
0 |
90 |
Json行数:0.8w |
300ms |
110 |
40 |
30 |
0 |
90 |
Json行数:0.6w |
230ms |
100 |
30 |
60 |
30 |
40 |
Json行数:0.4w |
150ms |
80 |
0 |
20 |
0 |
50 |
Json行数:0.2w |
80ms |
40 |
20 |
10 |
0 |
10 |
由上述结果可以看到,使用json串来保存结果,加载的时间太长,不符合需求,之后将会改用bitmap来保存数据。
新测试:
测试目的:
原测试方案看起来是可行的,不过由于以上的方案与最终用于服务器的程序是有差别的,所以需要有一个新的测试。
原测试方案中,是先读取Json串,然后建立一个UCB类,然后再开始进行服务的。这就好比在服务器程序上自行用map实现了一个数据库。这样做的开销太大,在实际上的服务器构架上是不会这么用的。
新的测试方案应该基于这样一个假设:服务器程序通过用户发来的URL得到用户的UID,然后从服务器中读取保存好的UCB类并初始化,然后完成选择和更新动作,发给客户端。
这里我们先假设保存在服务器中的UCB类是通过json串保存的,这样,我们可以在UCB类中加上toString和readFromString两个函数,来完成模拟从服务器中读取json串的动作。在初始化了UCB类之后,保存在文本文件中即可。
测试条件:
主机:本机,intel 4700mq, 8G内存
Json串数量:2万条至300条
对应的tags:11000个至700个
对应的topics:550个至80个
时间花费:只统计readFromString, select_arm_N, update三个操作所用时间。
Select与update数量:200个,不足200时用最大数量。
测试结果:
表3:从Json串中初始化UCB类并进行推荐用时
Json行数 |
Tags数量 |
Topics数量 |
Tags:完成时间 |
Topics:完成时间 |
2万 |
11070 |
554 |
101.69 |
4.56 |
1.8万 |
10460 |
550 |
95.71 |
4.63 |
1.6万 |
9789 |
545 |
90.72 |
4.58 |
1.4万 |
9122 |
537 |
89.15 |
4.58 |
1.2万 |
8435 |
524 |
78.89 |
4.37 |
1.0万 |
7618 |
500 |
69.69 |
4.18 |
0.8万 |
6711 |
485 |
61.97 |
4.37 |
0.6万 |
5677 |
449 |
49.15 |
3.80 |
0.4万 |
4466 |
391 |
38.70 |
3.38 |
0.2万 |
2892 |
300 |
25.52 |
2.64 |
1.5千 |
2340 |
257 |
20.32 |
2.21 |
1千 |
1760 |
194 |
15.88 |
1.63 |
0.5千 |
1033 |
130 |
9.03 |
0.98 |
0.3千 |
688 |
79 |
5.61 |
0.51 |
结论:
上表中,tags和topics单位是个,他们是用来当做key,即商品的种类,tags和topics越多,UCB类中保存的种类越多。种类越多,初始化的时间越长,结论与假设是一致的。
对应的完成时间单位是ms。
1. 每100个key对应的运行时间在0.8-1.0ms之间。
2. 使用只有600个种类的topics作为key,可以在6ms之内完成
3. 即使使用tags,1万个tags用时100ms,还是可以接受的结果
因此,在这里可以使用Json作为保存UCB类的数据结构,因此,该UCB类已经可以直接用于推荐系统。之后的工作可以根据需求再改进UCB类。