前言:
之前的工作已经保证了算法基本上是按照我们想要的方式在运行,第二个重要的问题就是,如何保证算法在需要的时间中完成工作。毕竟用户可没有多少耐心来等待页面刷新的。
测试的方法是使用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类。