为什么处理一个排好序的数组比未排序的数组要快?

有已排好序的数组,要求输入数后按原来排序规律插入数组中 有已排好序的数组,要求输入数后按原来排序规律插入数组中,这是题目。 之前在我写的  改变矩阵元素的位置 中我曾说过,要移动数字,可以先挖一个坑然后将后面的一个个补上,最后在把挖出来的填上 于是我试着用这个思路做了一次,但是挖坑算法给自己挖了个坑,坑了自己,弄了整个晚上。。。 #include int main() { int i=0,j=0,t=0; int a[11]={ 阅读详情

这是stack overflow上一个非常火热的问题:

为什么对数组排序能提高执行效率?先看下面的代码,执行分为:

  1. 生成随机数放入数组

  1. 对数组进行排序

  1. 对数组中的数字进行累加

publicclassMain {publicstaticvoidmain(String[] args){
        // 生成随机数int arraySize = 32768;
        int data[] = newint[arraySize];

        Random rnd = new Random(0);
        for (int c = 0; c < arraySize; ++c)
            data[c] = rnd.nextInt() % 256;

        // 排序
        Arrays.sort(data);

        // 累加,测试执行时间long start = System.nanoTime();
        long sum = 0;
        for (int i = 0; i < 100000; ++i) {
            for (int c = 0; c < arraySize; ++c) {
                if (data[c] >= 128)
                    sum += data[c];
            }
        }

        System.out.println((System.nanoTime() - start) / 1000000000.0);
        System.out.println("sum = " + sum);
    }
}

排序后的执行时间:2.2350021s 未排序后的执行时间:6.385857s

可以发现:排序后的执行时间是未排序的执行时间的3倍。

为什么会这样,这就跟分支预测有关系,什么是分支预测呢?

计算机在执行某一条指令的过程中,会分为四个步骤:

每个步骤会有对应的电路组件负责。

假设现在有一段程序对应的计算机指令为:

那么计算机应该先执行指令1,然后根据指令1的结果看接下来应该执行哪条指令,假设接下来要执行的就是指令2,那指令流水线会是下图吗?

假设每个步骤要1毫秒,那执行完这两条指令就需要8毫秒,但是前面说过,指令的四个步骤是由特定的组件来执行的,所以其实可以这么执行:

在解码指令1的过程中,就可以读取指令2了,这样执行完两条指令只需要5毫秒,如果后续指令也按这个节奏执行,那么效率提升会很大,比如串行执行3条指令需要3*4=12毫秒,而并行执行3条指令只需要6毫秒,快了一倍了。

那这个跟分支预测有什么关系呢?

我们在来看

假如指令2是一条判断指令,根据判断结果,要么执行指令3,要么执行指令4。

如果不对判断结果进行预测,那么就只能等指令2执行完之后才知道接下来要执行哪条指令,那指令流水线就是下面这样:

执行这三条指令要9毫秒。

但是,如果在执行指令2之前,我们就能预测出指令2的判断结果,假如预测的是指令3,那么指令流水线就可以这样:

相当于在解码指令2的时候,就同时去读取指令3,如果执行完指令2后,发现判断结果和预测的结果是一致的,那么就可以直接把指令3的结果写回了,这样就大大提高效率,执行这3条指令只需要6毫秒。

当然如果执行完指令2后,发现预测错了,那么就不能把指令3的结果写回了,而是得读取并执行正确的指令。

以上就是分支预测,简单总结一下就是,计算机会对分支,比如判断指令的结果进行预测,从而提前去做一些事情,而不是等判断结果出来后才去做事情。

回到上面的Java代码:

for (int c = 0; c < arraySize; ++c) {
    if (data[c] >= 128)
        sum += data[c];
}

if语句就相当于是一个判断指令,根据判断结果就会有两个分支:

  1. 要么进行累加

  1. 要么取数组中的下一个数字。

所以,当执行if语句时,计算机就可以进行预测:

  1. 比如预测当前判断的数字是大于128的,那么就可以在判断结果没有出来之前提前进行累加

  1. 或者预测当前判断的数字是小于128的,那么就可以在判断结果没有出来之前提前取下一个数字

只要预测对了,就能提高执行效率,所以,我们要做的就是尽可能让计算机能预测准确,这就是数组排序的作用。

比如计算机在执行指令过程中,发现连续10个数字都是大于128的,那么就可以预测接下来的一个数字也是大于128的,所以只要数组是排好序的,那么这个预测就是正确的,从而也就提高了执行效率。

以上,就是分支预测,不知道大家看明白没...

Keil环境下单片机串口通信实战:如何用printf发送中文(附完整代码) 本文详细解析了在Keil开发环境下,单片机通过串口通信发送中文信息时产生乱码的根本原因及解决方案。核心在于理解并统一编码(如GB2312或UTF-8),并正确重定向printf函数。文章提供了针对STC89C52和STM32F103的完整代码示例,涵盖工程配置、编码设置、调试技巧,帮助开发者实现稳定可靠的中文串口输出。 阅读详情

相关推荐

生物信息学新手必看:MAFFT多序列比对从安装到实战(附参数优化技巧)

本文为生物信息学新手提供了MAFFT多序列比对工具的完整指南。从Linux环境下的安装部署,到核心算法策略(如FFT-NS-i、L-INS-i)的选择逻辑,再到空位罚分等关键参数的深度解析与优化技巧,手把手教你完成从原始序列到高质量比对结果的实战流程,为后续进化树构建等分析奠定坚实基础。

weixin_29230773的博客 485

java源码系列:技术的本质?数组到底是什么?数组为何查询快插入慢?

10年以上老程序猿,带你温习,【数组】到底是什么?此知识点也是面试常问点

鲁迷那的专栏—坚持实践后再写出来! 1197

在MCUXpresso上通过J-link烧写KW45

背景: KW45B是nxp 的ble npi产品,其使用的IDE为MCUXpressso或者IAR,MCUXpressso有一些bug,但是由于MCUXpressso阅读查找代码相对IAR容易,所以我经常使用的MCUXpressso进行开发。当然IAR也有其优势,比如编译、烧写速度相对MCUXpressso更快,是比较通用的一个平台,而MCUXpressso是NXP独有的。 Kw45有两种烧写方式,一是使用MCUlink,二是使用Jlink。NXP ble 产品线提供的IDE资料里有最新的15.0版本的

weixin_41889258的博客 2859

JAVA中数组与集合类的比较

     本来想写一篇《JAVA容器论》的,讲的是JAVA里容器类的一些知识,原因是前天和小付去面试被问到了关于JAVA容器的一些知识,有一点拿不准。但是发现容器的东西还真不少,于是决定分开来写,我想没有人喜欢大部头的。这里所谓“容器”就是能够持有数据(对象的reference或primitives)集合的数据结构,比如我们熟悉的数组、链表和Hash表等等。借这个机会想把JAVA的容器类相关的知识...

Aladdin的思考 677

树莓派 SPI操作

扩展板配备一款0.96inch,128864分辨率的oled显示屏,通过SPI控制,先上显示效果图。由于程序过长,在这里我就不把代码全部贴出来了,只是简单讲解一下spi的操作函数。管脚如下如所有,左边方框的管脚分别为MOSI MISO SCLK,左边CE0,CE1为两个片选管脚,分别对应上图中的spidev0.0,spidev0.1两个设备。下载spidev库,复制到树莓派,并行运行如下命令解压安装。spi设备,此处设备为/dev/spi-decv0.0。在/dev路径下面,我们可以发现两个spi设备。

weixin_46529898的博客 914

Kindle使用USB数据线传书封面无法显示问题

不建议按这个解决封面问题,首先USB多次插拔麻烦,其次就是我起初按博主方法没啥问题,后面无论我怎么个顺序都出现了‘暂无图片’,我的建议是在亚马逊退出国内只能USB传书的情况下,下载一个calibre 和。飞行模式下用calibre传书到kindle ,然后用Fix Kindle Ebook Cover 修复一下,后面你要继续飞行模式还是连网随你便,两步完事。2,‘’发送到设备’的时候也最好选择 ‘发送特定格式至’ 选择具体的电子书格式,你的电子书是azw3就选azw3,是mobi就选mobi。

meser88的博客 7419

数据结构|数组为什么这么快?

我相信在很多地方,大家在进行数据结构的比较的时候,说到数组,第一反应就是—快,但是为什么快呢?数组到底快在哪里呢?不知道大家是否有思考过这个问题,这篇文章,我就讲讲我对数组的一些看法,抛砖引玉,希望大家多多交流! 文章目录数组到底哪里快?查找快吗?为什么数组能支持随机访问呢?答案:举例分析: 我们要分析的第一个问题是: 数组到底哪里快?查找快吗? 可能有的同学第一反应利用数组进行查找的话,时间...

做一个认真的程序员 3419

2024年数字IC秋招-格科微-数字电路设计工程师-笔试题

笔试题型:简答题(9个)笔试平台:牛客(电脑监控)笔试时间:2h。

qq_42135020的博客 1605

为什么处理排序数组比未排序数组快

    今天在群里看到一个有意思的问题——为什么处理排序数组比处理没有排序的数组要快,这个问题来源于 StackoverFlow,虽然我看到代码略微知道原因,但是模模糊糊不够清晰,搜了很多博客也讲的不够明白,所以就自己来总结了。     首先来看一下问题,下面是很简单的一段代码,随机生成一些数字,对其中大于 128 的元素求和,记录并打印求和所用时间。 import java.util.Array...

weixin_34250434的博客 315

【一看就会】Autoware.universe中静态绕障路线的生成逻辑

在路径行为规划中,前期根据地图和起点终点,生成了一组连续可行的路径段序列(lanelets),然后后续路径行为规划,又会进行起始点,终止点,避障绕障路径的路径规划,并且会调用route_handler中的函数,进行中心线生成,最后生成路径,后续再给速度行为规划进行速度规划。在autoware.universe的规划中,是基于规则的规划,而其中的规则又是为了解决不同场景的。而这些场景,大部分是为了解决路上障碍物(静态、动态、行人、车辆等等)。

weixin_48386130的博客 321

mjlab & MimicKit 宇树 G1 人形机器人强化学习训练部署

基于mjlab框架训练Unitree G1人形机器人执行双旋踢的示例。参考动作源自Jason Peng的MimicKit项目。数据转换脚本(MimicKit pkl → mjlab csv)完整训练结果与超参数预训练ONNX检查点用于部署实体硬件部署指南⚠️ 免责声明仅用于教育目的。对于因尝试复现此处展示结果而导致的财产损失或人身伤害,我们概不负责。操作硬件时请谨慎行事并保持良好判断力。

2506_90492529的博客 1700

6.4有一个已排好序的数组,要求输入一个数后,按原来排序的规律将它插入数组中。

//C程序设计第四版(谭浩强) //章节:第六章 利用数组处理批量数据 //题号:6.4 //题目:有一个已排好序的数组,要求输入一个数后,按原来排序的规律将它插入数组中。 #include &lt;stdio.h&gt; int main() { int a[40]={1,0},i,j,n,x; printf("请输入数组元素的个数:"); scanf("%d",&amp;n); p...

weixin_44589540的博客 3万+

基于STM32设计的水质检测系统_333

水质安全对生态环境、农业生产、工业制造以及人类健康至关重要。针对传统水质检测方式检测周期长、成本高、实时性差的问题,本项目设计并实现了一种基于STM32的水质检测系统。系统采用STM32F103RCT6作为主控芯片,集成水温、pH值、电导率和浊度等传感器,能够实时采集水质数据,并通过OLED显示屏进行本地显示。同时,利用Air724UG 4G模块通过MQTT协议将数据上传至华为云IoT平台,实现远程监测。用户可通过Qt5开发的Android手机APP和Windows上位机查看水质数据,并接收超限报警提示。此

713

有一个已经排好序的数组,今输入一个数,要求按照原来排序的规律将它插入数组中

有一个已经排好序的数组,今输入一个数,要求按照原来排序的规律将它插入数组中 假设原数组是按照升序进行排序,那么需要将输入的值进行挨个比较,从第一个数开始,若小于输入的数,则和下一个数比较,直到大于输入的数,则将输入的值放在该位置,从大于他的数起往后移一位。 #include&lt;stdio.h&gt; int main() { int a[10]={1,3,5,7,9,11,13,15,17,...

一只睡不醒的猪 2万+

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

有一个已排好序的数组,要求输入一个数后,按原来排序的规律将它插入数组中——C语言

1 概述 有一个已排好序的数组,要求输入一个数后,按原来排序的规律将它插入数组中。 2 解法 //C程序设计第五版(谭浩强) //章节:第六章 利用数组处理批量数据 //题号:6.4 //题目:有一个已排好序的数组,要求输入一个数后,按原来排序的规律将它插入数组中。 #include <stdio.h> int main() { int x[100],i,j,n,y; prin...

我是张跑跑 5563

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

有一个以及排好序的数组,要求输入一个数后,按原来排序的规律将它插入数组中

/*有一个已经排好序的数组,要求输入一个数后,按原来排序的规律将它插入数组中*/ #include <stdio.h> #define N 10 int main() { int i,j,t,n,min,max; int a[N]={2,4,8,11,20}; //printf("请输入数字:\n"); //for(i = 0;i < N;i ++) //sca...

qq_40834200的博客 3092

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

有一个已经排好序的数组,今输入一个数,要求按原来排序的规律将他插入数组中。

/* * Copyright (c) 2012, 烟台大学计算机学院 * All rights reserved. * 作 者: 刘同宾 * 完成日期:2012 年 11 月 24 日 * 版 本 号:v1.0 * 输入描述: * 问题描述:有一个已经排好序的数组,今输

得之坦然,失之淡然 3万+

已有一个已排好序的数组,要求输入一个数后,按原来排序的规律将它插入数组中

已有一个已排好序的数组,要求输入一个数后,按原来排序的规律将它插入数组中。题为c基础程序设计(第五版)谭浩强 课后习题第6章第4题。

fashi的博客 4241

有一个已经排好序的数组,现输入一个数,要求按原来的规律将它插入数组中。——C与C++实现

题目:一个已经排好序的数组,现输入一个数,要求按原来的规律将它插入数组中。(本例中输入的是一个升序的数组) 程序分析: (1)判断输入的数是否大于数组中最后一个元素,如果成立,将输入的数插入数组的末尾,反之执行(2)。 (2)通过循环,将输入的数插入第一个比之大的元素前边,之后的元素一次向后移动。 C实现: C运行结果: C++实现: C++运行结果: ...

ling08140814的博客 1万+

C语言:向排好序的数组中插入数据

题目:数组中已按从小到大顺序存有10个整数,键盘输入一个整数插入到数组中,插入后的数据还是按顺序排列的。 实例解析: 解法1: 要向排好序的数据中插入一个数据x,必须首先确定x应该插入到数组的何处,然后再行插入。 要确定x应插入到何处,需要将x依次与数组中的每个元素进行比较,若x小于某元素,则该元素的位置便是x应该插入的位置。这个过程可用下面代码实现。 for(i = 0; i    

小乔的博客 1万+

判断一个数组是否排好序

#include <iostream> using namespace std; int main() { int a[100],j=1,s=0; int n; cin>>n; for(int i=0; i<n; i++) cin>>a[i]; while((j<n)&&(a[j-1]<=a[j])) { j+=1; if(j==n)

qq_43742497的博客 1734

有一个已经排好序的数组,要求输入一个数后,按原来排序规律将它插入数组中。

代码: #include <stdio.h> #define N 11 int main(){ //原数组是升序 int a[N]={1,4,6,9,13,16,19,28,40,100}; int n,num; printf(“原数组的数为:\n”); for(n=0;n<N-1;n++) printf("%d “,a[n]); printf(”\n"); printf(“请输入一个数:\n”); scanf("%d",&num); for(n=0;n<=N-2;n+...

weixin_48199671的博客 1万+

有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。-多语言

有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。首先判断此数是否大于最后一个数,然后再考虑插入中间的数的情况,插入后此元素之后的数,依次后移一个位置。

分享编程知识与技巧 致力于技术交流与学习 找我合作私聊 有偿解决计算机问题 946

有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。

题目:有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。 程序分析:首先判断此数是否大于最后一个数,然后再考虑插入中间的数的情况,插入后此元素之后的数,依次后移一个位置。 public class Prog30 { public static void main(String[] args) { int[] A = new int[] { 0, 8, 7, 5, 9...

Carlos的博客 757

c语言作业已有一个已排好序的数组,C语言——实例039 有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中...

第一个程序:有bug,但没发现/*Name:Copyright:Author:Date: 31/07/17 11:42Description:【程序39】题目:有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。1. 程序分析:首先判断此数是否大于最后一个数,然后再考虑插入中间的数的情况,插入后此元素之后的数,依次后移一个位置。?*/#include int main(){int...

weixin_39565332的博客 2523
上一篇: 真香,Java架构进阶全靠这份阿里大佬整理的笔记,图文并茂
下一篇: 舒适!兴趣为伴,苦学5000页Java学习手册,知识不停学,薪资绩效蹭蹭涨
Java技术那些事儿
博客等级 码龄5年 2306粉丝 2584原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值