首页 > 其他分享 >常数优化1

常数优化1

时间:2022-12-03 11:45:33浏览次数:38  
标签:10000 int sum Union union 数组 常数 优化

本文介绍的常数优化方法能使代码加速到原来的一半甚至更快

使用union类

定义

union是一种特殊的类,定义方法如下(定义在main内或main外都可以)

union Union{
	int a;
	double b;
	char c;
};
Union u;

互斥的特性

union的所有成员存储在同一个地址上,因此在任意时刻,union中只能有一个成员有值,例如以下代码就是错误的

U.a = 27;
U.b = 6.7;
cout << U.a;
return 0;

正是由于此特性,union不仅节约空间,而且使得变量更容易被存储到高速缓存中,从而起到常数优化作用

在union中加入对象

可以在union中加入对象,例如

class Class{
	int a;
};
union Union{
	Class test;
	int n;
};

以上代码如果要通过union修改a的值,需要将a定义为public,如下

#include<bits/stdc++.h>
using namespace std;
class Class{
public:
	int a;
};
union Union{
	Class test;
	int n;
};
Union u;
int main(){
    u.test.a = 114;
    cout << u.test.a;
    return 0;
}

以上代码可以正常运行,如果将第4行的public改为private或protected,则不能编译

一个循环分多路执行

以下两段代码

int sum = 0;
for(int i = 1; i <= n; i++){
	sum += a[i];
}

int sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0;
for(int i = 1; i <= n; i += 4){
	sum1 += a[i];
	sum2 += a[i + 1];
	sum3 += a[i + 2];
	sum4 += a[i + 3];
}

前者运行时间大约是后者的两倍

位运算小技巧

这部分引自《论程序底层优化的一些方法和技巧》

无分支地求绝对值

int abs(int x){
	int y = (x >> 31);
	return (x + y) ^ y;
}

无分支地求最大值

int max(int x, int y){
	int m = (x - y) >> 31;
	return y & m | x & (~m);
}

不使用除法求平均数

int average(int x, int y){
	return (x & y) + ((x ^ y) >> 1);
}

不使用中间变量交换两个数(节约空间)

void swap(int &x, int &y){
	x ^= y;
	y ^= x;
	x ^= y;
}

使原来为a的x变为b

	x ^= a ^ b;

高维数组寻址非常慢

举个例子,与其写

if(a[i][j][k][l] > a[i][j][k - 1][l] + a[i][j][k][l - 1]){
	a[i][j][k][l] += a[i][j][k - 1][l] + a[i][j][k][l - 1];
}

不如写成

int &p = a[i][j][k][l], tmp = a[i][j][k - 1][l] + a[i][j][k][l - 1];
if(p > tmp){
	p += tmp;
}

这样优化的效果在dp中尤其明显

另外,某一维很小,如

dp[10000000][2]

则应当定义为大小为10000000的结构体或两个数组,如下

struct DP{
	int a, b;
}dp[10000000];
//or
dp0[10000000], dp1[10000000];

而在这两种写法中,又推荐使用结构体

高维数组尽量按内存连续访问

不能避免使用高维数组时,应注意这一点

以下两段代码

int a[10000][10000], sum = 0;
for(int i = 0; i < 10000; i++){
	for(int j = 0; j < 10000; j++){
		sum += a[i][j];
	}
}

int a[10000][10000], sum = 0;
for(int i = 0; i < 10000; i++){
	for(int j = 0; j < 10000; j++){
		sum += a[j][i];
	}
}

后者运行时间大约是前者的3倍,如果数组的大小是2的整数次幂,后者运行时间会达到前者的10倍以上

避免将多维数组某一位的大小定义为2的幂

根据《论程序底层优化的一些方法和技巧》中的测试,遍历一个2048 * 2048的数组比遍历一个2049 * 2049的数组慢大约4倍,所以,请不要将多维数组某一维的大小定义为2的幂,尽量将多维数组的每一维大小都定义为奇数。

ps.尤其是开状压dp数组,记得大小+1

标签:10000,int,sum,Union,union,数组,常数,优化
From: https://www.cnblogs.com/xj22yangyichen/p/16947240.html

相关文章

  • 常数优化2
    本文介绍的常数优化方法或者能使代码略微加速,或者是一般人写代码时就习惯写成较快的方式注意STL函数的时间复杂度例1:以下遍历char[]的两种方法for(inti=0;i<str......
  • 【磨刀霍霍向数模】系列之凸优化求解利器cvxpy
    CVXPY是Python中内置的解决凸优化问题的模块,其可以自动转化问题为标准形式,调用解法器,求解。本文介绍求解的常见思路方法。1.设定变量cvx.Variable(shape=(),name=Non......
  • 子查询优化之 Semi-join 优化 | StoneDB 研发分享 #2
    缘起StoneDB在列式存储引擎Tianmu的加持下,在大多数场景下相对MySQL都会有大幅性能提升。当然,这是需要工程师不断优化代码才能做到的,而且,性能好也需要通过基准测试才......
  • 尾调用及递归优化
    参考文章尾调用优化-阮一峰;基本概念一、尾调用一个函数的最后一步是调用另一个函数,并返回。注意点是,返回的是一个函数的调用(执行)。//最简形式functionf......
  • 编译器优化丨Cache优化
    摘要:本文重点介绍几种通过优化Cache使用提高程序性能的方法。本文分享自华为云社区《编译器优化那些事儿(7):Cache优化》,作者:毕昇小助手。引言软件开发人员往往期望计算机......
  • 容器开发运维人员的 Linux 操作机配置优化建议
    "工欲善其事必先利其器",作为一个PAAS平台架构师,容器相关技术(docker,k8s等)是必不可少的.本文简单介绍下我自己的Linux操作机配置.提升工作效率,提高使用体验.❤️......
  • 数据中台 | 如何优化企业"数据消费"策略
    随着大数据时代的到来,企业的数据消费模式发生转变并不断升级。企业正在清晰地认识大数据的价值并加以利用,通过数据分析找出并满足消费者的需求,在这场数字变革中实现转型。因......
  • weblogic优化
    一、登录web界面卡顿[root@localhostsecurity]#find/-namejava.security/apppackage/jdk1.8.0_311/jre/lib/security/java.security[root@localhostsecurity]#cat......
  • 秒杀优化-异步秒杀思路
    当用户发起请求,此时会请求nginx,nginx会访问到tomcat,而tomcat中的程序,会进行串行操作,分成如下几个步骤1、查询优惠卷2、判断秒杀库存是否足够3、查询订单4、校验是否是......
  • 记一次接口优化操作
    项目正式上线之后,后期主要是不断地进行版本迭代,开发新的功能。自己参与开发的项目正式开始使用后,人数还不少,早上高峰期的时候一个接口一个小时的请求数达到约3万。而......