先说一下发生的事情吧。

  去年某时,一位朋友找到我,说他面临一个很严重的问题,如果此问题解决不了,他们的产品就不能被用户所接受,说白了就是白做了,拿不到钱。

  他们给用户开发一套软件,但是用户通过文本导入数据过程中,软件直接假死,通过检查,用户导入数据大概有50万条之多,平时做测试时,他们通过文本导入数据大概在1万条左右,没想到数据量从1万增加到50万,程序竟然会假死。此问题如果不能很好解决,估计用户是不会买账了。

  通过分析,他所要做的事情大致可以缩减如下:

    1.总共10万个电话号码;

    2.电话号码中有重复和错误;

    3.查找出正确的号码(不重复)。

  问题经过精简之后,我看着似曾相似,当然估计有些读者应该知道怎么做了。

  我先说一下朋友的做法,大致如下(精简,剔除不必要的成份):

    1.先用正则过滤一遍10万条数据,找出错误的;

    2.用List.Contains验证重复数据,List.Add添加不重复数据;

    3.最终从List中取出正确的数据。

  当然朋友将List换成Hash是做了一些效率上的提升,但是不明显。

  听他把事情讲清楚后,看着他满面愁容,能理解他的心情,我以前私接项目,也懂得一个道理:要么不做,要么就做好;半途而废,耗时耗力耗财。而且一个人到了这种状态,成与不成的命运竟然跟一个小小的常备功能息息相关,而自己又做不出这个功能,眼看自己耗费那么多的精力、心血、时间在上面的一个产品,就要变成废品,就像是亲手养育的孩子要被无情扼杀,那种心情可想而知。

  万事开头难,闯过这一关,之后道路就相对平坦了,任谁都不想在起步的道路中被阻碍,这个世界上没有那么多打不到、压不扁、锤不烂的刚豆豆型人物,一旦信心被磨灭,就再也走不远了。

  我只是劝他别着急,然后给他做了两段测试代码,他看完后像抓到了救命稻草一般,都把我这个大活人给漠视了,仓皇离席。

  我的做法大致如下(精简):

    1.先对10万数据排序

    2.对比前后两条数据(这个我之后会详细说明为什么这么做)

    3.筛选出正确数据

  这么改动之后,朋友的一个假死功能,瞬间生龙活虎,在数秒就能处理好50万的数据样本。

   作为报酬,朋友事后往我账户里打入一万,这也是我们聊天时他半开玩笑的一个承诺,也就区区几行代码,这几行代码确实值钱了。按照他原想,是要拿出三至五万找人来优化代码的。

  说道这里 ,貌似部分读者还是摸不着头脑。那么我就上测试代码以及测试结果。也许用实验证明远比语言要来的简单和真实。

以下是我写的一段Java测试代码:

 1 public class appMain {
 2     final static int _capacity = 1000000;
 3     final static Random rand = new Random(System.currentTimeMillis() + _capacity);
 4     static ArrayList<String> list = new ArrayList<String>(_capacity);
 5     static ArrayList<String> newlist = new ArrayList<String>(_capacity);
 6
 7     public static void main(String[] args) throws InterruptedException {
 8         long ts = System.currentTimeMillis();
 9         int modVal = _capacity / 3;
10         for (int i = 0; i < _capacity; i++) {
11             rand.setSeed(i);
12             list.add(Integer.toString(Math.abs(rand.nextInt() % modVal)));
13         }
14         ts = System.currentTimeMillis() - ts;
15         System.out.println("生成时间 :" + ts);
16
17         test1();
18         test2();
19     }
20
21     static void test1() {
22         newlist.clear();
23         int repetition = 0;
24         long ts = System.currentTimeMillis();
25         for (String s : list) {
26             if (!newlist.contains(s))
27                 newlist.add(s);
28             else {
29                 repetition++;
30             }
31         }
32         ts = System.currentTimeMillis() - ts;
33         System.out.println("------ 插入检查方法 -------");
34         System.out.println("查找时间 :" + ts);
35         System.out.println("重复 :" + repetition);
36         System.out.println("正确 :" + newlist.size());
37     }
38
39     static void test2() {
40         newlist.clear();
41         int repetition = 0;
42         long ts = System.currentTimeMillis();
43
44         Collections.sort(list);
45         String str = list.get(0);
46         int max = list.size();
47         for (int i = 1; i < max; i++) {
48             if (str.equals(list.get(i))) {
49                 repetition++;
50                 continue;
51             }
52             newlist.add(str);
53             str = list.get(i);
54         }
55         newlist.add(str);
56
57         ts = System.currentTimeMillis() - ts;
58         System.out.println("------ 排序检查方法 -------");
59         System.out.println("查找时间 :" + ts);
60         System.out.println("重复 :" + repetition);
61         System.out.println("正确 :" + newlist.size());
62     }
63 }

test1(),是我朋友使用的方式,test2()是我提供朋友的方式,运行结果出乎意料。

/*
条件:capacity = 100000结果:生成时间 :33
------ 插入检查方法 -------
查找时间 :6612
重复 :76871
正确 :23129
------ 排序检查方法 -------
查找时间 :91
重复 :76871
正确 :23129
*/
/*
条件:capacity = 1000000结果:
生成时间 :392
------ 插入检查方法 -------
查找时间 :1033818
重复 :703036
正确 :296964
------ 排序检查方法 -------
查找时间 :1367
重复 :703036
正确 :296964
*/

当数据量达到10万条的时候,查找时间比差不多90倍的差距了;当数据量达到100万时,我这边测试数据已经卡死在test1(),而test2()依然能在数十秒内反馈结果。

先来说一下我这些代码:

 1         Collections.sort(list);
 2         String str = list.get(0);
 3         int max = list.size();
 4         for (int i = 1; i < max; i++) {
 5             if (str.equals(list.get(i))) {
 6                 repetition++;
 7                 continue;
 8             }
 9             newlist.add(str);
10             str = list.get(i);
11         }

Line 1:排序,加入list排序后的结果是[1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]

Line 2:初始str = 1;

从Line 4开始进入循环:

Line 5:判断str是否和当先selector值相等(暂借我们认为list.get(i)是一个指针),如果相等则跳过以下步骤进入下一个循环

Line 9:将str = 1,加入newlist尾

Line10:将当前selector值赋给str,此时str=2,进入下一个循环

...

这种语言解释我个人觉得特别麻烦,我还是写段代码让程序告诉你它怎么执行的。

 1 public class appList {
 2     static ArrayList<String> list = new ArrayList<String>();
 3     static ArrayList<String> newlist = new ArrayList<String>();
 4
 5     public static void main(String[] args) {
 6         for (int i = 1; i < 5 + 1; i++) {
 7             for (int j = 0; j < i; j++) {
 8                 list.add(Integer.toString(i));
 9             }
10         }
11         System.out.println("list初始值 " + list.toString());
12         // print输出值 [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5]
13
14         String str = list.get(0);
15         int max = list.size();
16         for (int i = 1; i < max; i++) {
17             Print(i);
18             if (str.equals(list.get(i))) {
19                 PrintNew();
20                 continue;
21             }
22             newlist.add(str);
23             System.out.println("add\t" + str);
24             str = list.get(i);
25             PrintNew();
26         }
27
28         newlist.add(str);
29         System.out.println("add\t" + str);
30         PrintNew();
31
32         System.out.println("newlist值 " + newlist.toString());
33         // print输出值 [1, 2, 3, 4, 5]
34     }
35
36     static void PrintNew(){
37         StringBuilder stringBuilder = new StringBuilder();
38         stringBuilder.append("newlist\t");
39         for (int i = 0; i < newlist.size(); i++) {
40             stringBuilder.append(newlist.get(i));
41             stringBuilder.append(",");
42         }
43         System.out.println(stringBuilder.toString());
44         System.out.println();
45     }
46     static void Print(int pos) {
47         StringBuilder stringBuilder = new StringBuilder();
48         stringBuilder.append("list\t");
49         for (int i = 0; i < list.size(); i++) {
50             if (i == pos) {
51                 stringBuilder.append("[");
52                 stringBuilder.append(list.get(i));
53                 stringBuilder.append("],");
54             } else {
55                 stringBuilder.append(list.get(i));
56                 stringBuilder.append(",");
57             }
58         }
59         System.out.println(stringBuilder.toString());
60     }

以上代码执行结果:

list初始值 [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5]
list       1,[2],2,3,3,3,4,4,4,4,5,5,5,5,5,
add    1
newlist    1,list       1,2,[2],3,3,3,4,4,4,4,5,5,5,5,5,
newlist    1,list       1,2,2,[3],3,3,4,4,4,4,5,5,5,5,5,
add    2
newlist    1,2,list       1,2,2,3,[3],3,4,4,4,4,5,5,5,5,5,
newlist    1,2,list       1,2,2,3,3,[3],4,4,4,4,5,5,5,5,5,
newlist    1,2,list       1,2,2,3,3,3,[4],4,4,4,5,5,5,5,5,
add    3
newlist    1,2,3,list       1,2,2,3,3,3,4,[4],4,4,5,5,5,5,5,
newlist    1,2,3,list       1,2,2,3,3,3,4,4,[4],4,5,5,5,5,5,
newlist    1,2,3,list       1,2,2,3,3,3,4,4,4,[4],5,5,5,5,5,
newlist    1,2,3,list       1,2,2,3,3,3,4,4,4,4,[5],5,5,5,5,
add    4
newlist    1,2,3,4,list       1,2,2,3,3,3,4,4,4,4,5,[5],5,5,5,
newlist    1,2,3,4,list       1,2,2,3,3,3,4,4,4,4,5,5,[5],5,5,
newlist    1,2,3,4,list       1,2,2,3,3,3,4,4,4,4,5,5,5,[5],5,
newlist    1,2,3,4,list       1,2,2,3,3,3,4,4,4,4,5,5,5,5,[5],
newlist    1,2,3,4,add    5
newlist    1,2,3,4,5,newlist值 [1, 2, 3, 4, 5]

转载于:https://www.cnblogs.com/preacher/p/6743031.html

这短短几行代码价值一万相关推荐

  1. 一个爬虫代码价值 7000 万

    一个爬虫代码价值 7000 亿,这样的代码你听说过吗? 这是一个爬取比特币密钥的代码. 比特币相信大家都有听说过,尤其最近比特币价格还突破了 5 万美元大关. 现在1 枚比特币就价值 35 万人民币. ...

  2. 一个爬虫代码价值 7000 万!

    这是「进击的Coder」的第 136 篇热点新闻 作者:痴海 来源:痴海 " 阅读本文大概需要 4 分钟. " 一个爬虫代码价值 7000 亿,这样的代码你听说过吗? 这是一个爬取 ...

  3. 震惊!!用图形界面装B居然只需要短短110行代码!!

    [序] 相信学习C或者C++的学生的最大的痛苦就是每次做的东西的都是CMD的黑框框 虽然很多人会慢慢爱上这个(呸),但是绝大多数的人都走向了另外一条路:图形界面 说到C++的图形界面,都不得不谈一下Q ...

  4. python爬虫实战:利用scrapy,短短50行代码下载整站短视频

    近日,有朋友向我求助一件小事儿,他在一个短视频app上看到一个好玩儿的段子,想下载下来,可死活找不到下载的方法.这忙我得帮,少不得就抓包分析了一下这个app,找到了视频的下载链接,帮他解决了这个小问题 ...

  5. 利用scrapy,短短50行代码下载整站短视频

    一.撕开爬虫的面纱--爬虫是什么,它能做什么 爬虫是什么 爬虫就是一段能够从互联网上高效获取数据的程序. 我们每天都在从互联网上获取数据.当打开浏览器访问百度的时候,我们就从百度的服务器获取数据,当拿 ...

  6. 短短60行代码搞定鸿蒙“二维码扫描”功能!

    开发者(KaiFaX) 面向全栈工程师的开发者专注于前端.Java/Python/Go/PHP的技术社区 可以实现的效果就是打开摄像头扫描一张二维码图片然后显示二维码里面的内容,看个视频一睹为快吧(界 ...

  7. 10行代码带你搞定目标检测(附代码)

    来源:大数据文摘 本文约2700字,建议阅读5分钟. 本文介绍采用代码搞定目标检测的技术. 计算机视觉是人工智能的一个重要领域,是关于计算机和软件系统的科学,可以对图像和场景进行识别.理解.计算机视觉 ...

  8. python爬虫代码1000行-Python爬虫教程(16行代码爬百度)

    最近在学习python,不过有一个正则表达式一直搞不懂,自己直接使用最笨的方法写出了一个百度爬虫,只有短短16行代码. 首先安装必背包: pip3 install bs4 pip3 install r ...

  9. 这几行代码,真的骚!

    点击关注公众号,实用技术文章及时了解 来源:编程技术宇宙 Hi,大家好. 我们知道,在计算机中要显示颜色,一般都是用R.G.B三个0-255范围内的整数来描述. 图片 这一点,即便你不是从事前端.客户 ...

最新文章

  1. 数据结构与算法之美day 6: 如何实现LRU缓存淘汰算法?
  2. python-水仙花数
  3. 当深度学习遇上量化交易——因子挖掘篇
  4. MySQL 高级 while循环
  5. VS2008如何添加 OLE/COM 对象查看器 .
  6. iOS NSString 与NSData转化
  7. 我的常用软件大公开!
  8. 让多核CPU占用率曲线听你指挥(Windows实现)——《编程之美》1.1学习笔记
  9. ubuntu16.04安装使用redis入门教程
  10. 在Eclipse上使用egit插件通过ssh协议方式上传项目代码的具体步骤
  11. Sqoop1 From PostgreSQL to Hdfs
  12. 用PHP ping 一个 IP
  13. 1. 英语邮件中经常用到的单句 (每次10句)
  14. 发那科数据服务器文件名,FANUC传输参数设置
  15. Python爬虫爬取小说 转换成epub格式
  16. 网络系统规划与设计的基本原则
  17. HDWiki的兼容性问题
  18. 智慧交通怎样利用科技打造一个“最强大脑”
  19. 关于考研的几个潜规则
  20. Sarcasm Detection with Self-matching Networks and Low-rank Bilinear Pooling

热门文章

  1. Flink 靠什么征服饿了么工程师?
  2. 如何提升代码可读性?阿里发布16条设计规约
  3. 如何高效排查系统故障?一分钱引发的系统设计“踩坑”案例
  4. java gui 层次结构_javaGUI教学图形界面的层次结构.ppt
  5. 从零点五开始用Unity做半个2D战棋小游戏(二)
  6. 3GU仙果游戏达成三地技术引擎战略合作联盟
  7. 数组声明为public final static缺陷
  8. 题目: javaweb前端素材管理系统(附免费下载源码链接)
  9. 入职体检——项目列表(12项)
  10. 炫“库”行动-人大金仓征文大赛—数据领域“新·独角兽”