10 行代码解决漏斗转换计算之性能优化

本文探讨大数据分析中的性能优化,强调时间、硬件与软件成本的重要性,介绍数据加载与算法优化技巧,以及并行计算的应用。

可阅读原文:http://c.raqsoft.com.cn/article/1539156910581?r=alice

大数据分析的性能优化,说道底,就优化一个事情:针对确定的一个计算任务(数据确定,结果确定),以最经济的方案得到结果。

这个最经济的方案主要考量三个成本:时间成本、硬件成本、软件成本。

  • 时间成本:根据计算任务的特点,能容忍的最长时间各不相同。那些 T+0 的计算任务,实时性要求就比较高,T+1 再算出结果就失去了意义。
  • 硬件成本:可以使用的硬件资源,对一个公司来说一般不是经常变化的,机器配置、可集群数量就那么多。即便使用云计算产品,也只是多了扩容的灵活性,成本是少不掉的。
  • 软件成本:编写出这个计算算法的人工费 + 软件环境的成本。这个成本也与前两项相关,程序控制力度粗犷一些,实现逻辑简单一些,程序就容易编写,那软件成本就会低一些,带来的副作用是运行时间超长或者需要昂贵的硬件。

这三个因素里面,一般对于计算任务来说,自然是越快越好,当然只要不慢过能容忍的时长,也就还算是有意义的计算;而硬件因素的弹性就比较小,有多少资源是相对固定的;所以,剩下的可以大做文章的就是软件成本了。软件成本里,程序员的工资是很重要的一项,而有没有顺手的软件环境让程序员能高效的把计算描述出来,就成了关键。最典型的例子就是理论上用汇编程序能写出所有的程序,但它明显不如 SQL 或 JAVA 做个常规计算来的容易。

说到 SQL 和 JAVA,成规模的计算中心的一些维护者估计也会皱眉,使用它们的时间越长,越能体会需求变动或优化算法过程中的痛苦,明明算法过程自己想的很清楚了,但编写成可运行的程序就困难重重。这些困难主要来自两个方面:

  • 首先,一些基础的数据操作方法是自己逐渐积累的,没有经过整体的优化设计,这些个人工具对个人的开发效率有不错的提升,但没法通用,也不全面,这个困难主要表现在用 JAVA 等高级语言实现的一些 UDF 上。
  • 第二,主要是思维方式上的,在生产场景下用习惯了 SQL 查询,在计算场景下遇到的性能问题自然而然就想通过优化 SQL 语句的方式把问题缓解掉。但实际上这可能是个温水煮青蛙的过程。越深入搞,把简单的过程问题越可能搞成庞大不可拆分的逻辑块,到最后只有原创作者或高手才敢碰它。我这个老程序员,十多年前刚入行的时候,八卦中耳闻过 ORACLE 的系统管理员,尤其是有性能优化能力的,比普通程序员贵多了,可见这个难题在数据规模相对较小的十年前已经凸显了。

(注:生产场景计算场景在初始阶段的软件系统里一般很难截然分开,数据都是从生产场景积累起来的,等积累多了,慢慢会增加计算需求,逐渐独立出计算中心和数据仓库。这个量变引起质变的过程,如果不在思维上转变,不引入新办法,那就将成为被煮的青蛙。)

为了节省读者的时间,我们先把性能优化的常用手段总结一下,方便有需求的用户逐条对比进行实际操作。

1、 只加载计算相关数据。

  • 列存方式存储数据;
  • 常用的字段和不常用的分开存储;
  • 用独立的维表存储维的属性,减少事实表的信息冗余;
  • 按照某些常用作查询条件的字段分开存储,如按年份、性别、地区等独立存储;

2、 精简计算涉及到的数据

  • 用来分析时,一些冗长的编号,可以序号化处理,用 1、2、……替代 TJ001235-078、 TJ001235-079、……,这样即能加快加载数据的速度,又能加快计算速度。
  • 日期时间,如果用字符串类型按照我们熟悉的格式 (2011-03-08) 存储,那加载和计算都会慢。前面这个日期可以存储成 110308 这样的数值类型,也可以存储成相对于一个开始时间的毫秒数(如相对于最早的数据 2010-01-01 的毫秒数)。

3、 算法的优化

  • 计算量小的条件写在前面,如 boolean 类型的判断,要早于字符串查找,这样用较少的计算就能排除掉不符合要求的数据;
  • 减少对大事实表的遍历次数。具体方法有:在一次遍历过程中,同时给多个独立的运算操作提供数据(后面会提到的集算器里的管道概念),而不是每个运算操作遍历一次数据;做 JOIN 时,在内存里的维表里检索事实表数据,而不是用每条维表数据去遍历一次事实表。
  • 查找时借用 HASH 索引、二分法、序号直接对位等方式加快速度。

4、 并行计算

  • 加载数据和计算两个步骤都可以并行。考量计算特点,根据加载数据和运算哪个量更大来判断瓶颈是计算机的磁盘还是 CPU,磁盘阵列适合并行加载数据,多核 CPU 适合并行运算。
  • 多机集群的并行任务,要考虑主程序和子程序的通讯问题,尽量把复杂计算独立到节点机上完成,网络传输较慢,要减少节点机之间的数据交换。

具体的实现方法可看原文:http://c.raqsoft.com.cn/article/1539156910581?r=alice

作者:xjl
来源:乾学院
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

<think>好的,我现在需要帮助用户了解NavMesh漏斗算法的实现和应用。首先,我需要回忆一下NavMesh和漏斗算法的基本概念。根据用户提供的引用内容,特别是引用[2]和[3],NavMesh用于生成可走区域的网格,漏斗算法则用于将路径多边形转换为具体路径点。 首先,我应该解释漏斗算法的基本实现步骤。根据引用[2],漏斗算法分为初始化漏斗区域、逐边处理顶点和收缩路径点。需要详细说明每一步的具体操作,比如如何设置左右边界,如何处理顶点导致边界收缩或扩张的情况。可能需要用一些比喻,比如拉绳子的过程,帮助用户理解。 接下来是应用场景部分。用户提到引用[3]中的服务器大规模寻路和动态避障,所以需要强调漏斗算法在长距离军、动态避障以及游戏中的应用。同时,结合引用[4]中的A*算法与漏斗算法的结合使用,可以说明在路径优化中的作用。 需要注意用户要求使用中文回答,并且内数学公式用$...$,独立公式用$$...$$。例如,在解释漏斗边界收缩时,可能需要用向量运算,但用户提供的引用中没有具体数学公式,所以可能不需要太多数学表达,但如果有相关概念,比如向量叉乘判断方向,可以适当加入。 还要确保生成相关问题,根据用户提供的示例,问题应围绕实现细节、应用场景和优化方法展开。需要检查引用中的信息是否足够支撑这些问题,比如引用[2]和[3]提到漏斗算法的优化和自创部分,可以生成相关问题。 需要检查是否遗漏了关键点,比如漏斗算法如何与A*结合,或者如何处理动态障碍。根据引用[4],A*用于生成多边形路径,而漏斗算法进一步优化路径点,所以需要明确两者的分工。 最后,确保回答结构清晰,分点说明实现和应用,并在末尾添加相关问题。同时,正确引用用户提供的参考文献,比如在说明路径优化时引用[3],在解释算法步骤时引用[2]和[4]。</think>### NavMesh漏斗算法的实现与应用 #### 一、算法实现原理 漏斗算法(Funnel Algorithm)的核心目标是将**多边形路径**转换为**最优路径点序列**,其实现分为以下关键步骤: 1. **初始化漏斗区域** 以起点为顶点,构造初始的左右边界(想象用绳子连接起点和第一个多边形的边)。左右边界由两个向量$v_{\text{left}}$和$v_{\text{right}}$定义,形成"漏斗"的开口区域[^2]。 2. **逐边处理顶点** 遍历多边形路径的每一条边,对边的两个顶点进判断: - **收缩操作**:若顶点在漏斗开口内,则更新对应边界(左顶点更新左边界,右顶点更新右边界)。 - **扩张操作**:若顶点超出当前开口,则触发路径点修正。例如,当左顶点超出右边界时,需将右边界最后一个有效点作为路径点,并重置漏斗区域。 3. **收缩路径点序列** 通过不断收缩左右边界,最终形成一条平滑的折线路径。此过程类似于"拉绳子"——在多边形边缘间找到最短穿路径[^2]。 ```python # 伪代码示例:漏斗算法核心逻辑 def funnel_algorithm(polygons): path = [start_point] left_boundary = [] right_boundary = [] for edge in polygons: for vertex in edge: if vertex在漏斗开口内: 更新对应边界 else: 添加路径点并重置漏斗区域 return path + [end_point] ``` #### 二、关键应用场景 1. **服务器端大规模寻路** 结合NavMesh与漏斗算法,可实现低CPU消耗的长距离军路径计算。引用[3]中提到通过**空间换时间**的优化策略,支持服务器端处理数千单位的并发寻路需求[^3]。 2. **动态避障优化** 在RVO(Reciprocal Velocity Obstacles)动态避障系统中,漏斗算法生成的路径可作为基础轨迹,再通过速度调整实现实时避障[^3]。 3. **游戏与机器人导航** 在Unity/UE4等引擎中,NavMesh+漏斗算法是标准导航方案。例如,《王者荣耀》中的AI移动、无人机集群路径规划等场景均有应用[^4]。 #### 三、性能优化要点 - **预处理网格数据**:通过NavMesh生成高质量的三角形/凸多边形网格,减少漏斗算法处理边界的复杂度。 - **路径点缓存**:对频繁请求的路径进缓存复用,如引用[3]中提到的**粗路径预计算**策略[^3]。 - **启发式剪枝**:在路径收缩过程中,提前剔除明显偏离方向的顶点,减少计算量[^4]。 #### 四、与A*算法的结合 1. **第一阶段**:使用A*算法在多边形网格中搜索可区域序列 $$f(n) = g(n) + h(n)$$ 其中$g(n)$为起点到当前多边形的实际代价,$h(n)$为当前多边形到终点的启发式估计值[^4]。 2. **第二阶段**:通过漏斗算法将多边形序列转换为精确路径点,消除A*路径的锯齿现象[^2]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值