到底谁的效率高??

在写代码的时候,常常使用if-else显得很麻烦,对于简单的赋值操作,我们可以使用三目运算符,但是与if-else比较的效率呢,不知道有没有人关注过。

 

现在来看看下面的测试:

public class Test1{
  public static void main(String[] argv){
      boolean b = true;
      if(b){
         b = false;
      }else{
         b = true;
      }
  }
}
 
public class Test2{
	public static void main(String[] argv){
		boolean b = true;
		b = (b==true?false:true);
	}
}

 进行javap分析:

D:>javap  -s Test1
Compiled from "Test1.java"
public class Test1 extends java.lang.Object{
public Test1();
  Signature: ()V
public static void main(java.lang.String[]);
  Signature: ([Ljava/lang/String;)V
}


D:>javap  -s Test2
Compiled from "Test2.java"
public class Test2 extends java.lang.Object{
public Test2();
  Signature: ()V
public static void main(java.lang.String[]);
  Signature: ([Ljava/lang/String;)V
public class Test2{
	public static void main(String[] argv){
		boolean b = true;
		b = (b ? false : true);
	}
} }


D:>javap  -c Test1
Compiled from "Test1.java"
public class Test1 extends java.lang.Object{
public Test1();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_1
   1:   istore_1
   2:   iload_1
   3:   ifeq



 11
   6:   iconst_0
   7:   istore_1
   8:   goto    13
   11:  iconst_1
   12:  istore_1
   13:  return

}


D:>javap  -c Test2
Compiled from "Test2.java"
public class Test2 extends java.lang.Object{
public Test2();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_1
   1:   istore_1
   2:   iload_1
   3:   iconst_1
   4:   if_icmpne



 11
   7:   iconst_0
   8:   goto    12
   11:  iconst_1
   12:  istore_1
   13:  return

}

 可见,进行的存储结构都相同,并且执行的指令条数也相同,只是执行过程中处理出现了一条语句的差异:

ifq还是if_icmpne,对于这两个,应该决定着效率问题,但是谁的更好呢?

 

增加:

根据下面回复的问题,确实有此种情况出现:

将Test2代码变化为:

public class Test2{
	public static void main(String[] argv){
		boolean b = true;
		b = (b ? false : true);
	}
}

 则相应的javap分析变为:

D:>javap -c Test2
Compiled from "Test2.java"
public class Test2 extends java.lang.Object{
public Test2();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_1
   1:   istore_1
   2:   iload_1
   3:   ifeq    10
   6:   iconst_0
   7:   goto    11
   10:  iconst_1
   11:  istore_1
   12:  return

}

 与Test1的比较得出:

D:>javap -c Test1
Compiled from "Test1.java"
public class Test1 extends java.lang.Object{
public Test1();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_1
   1:   istore_1
   2:   iload_1
   3:   ifeq    11
   6:   iconst_0
   7:   istore_1
   8:   goto    13
   11:  iconst_1
   12:  istore_1
   13:  return

}

 解析过程中少解析了一条指令,但是执行的代码条数相同。

也就是说,这样的写法不会提高任何效率,但是Test2.java代码相对简洁一些。

 

查看了一下class文件,分别为315字节(Test1.class)和307字节(Test2.class),去除命名差异引起的字节变化,大概也就是多出来的那条指令所引起的。

 

OK??

### 不同查询方式的性能比较及分析 在 SQL 查询中,组件索引和分组字段查询是两种常见的优化手段。以下将从多个角度分析两者的性能差异,并探讨多参数 `WHERE` 查询的效率。 #### 1. 组件索引与分组字段查询的性能对比 - **组件索引**:组件索引(如覆盖索引)能够显著减少磁盘 I/O 和 CPU 消耗,因为它允许查询直接从索引中获取所需数据,而无需回表访问实际数据行[^2]。例如,在查询 `SELECT name, email FROM users WHERE name = 'John'` 中,如果创建了 `(name, email)` 的联合索引,则可以完全避免回表操作。 - **分组字段查询**:当查询涉及大量分组操作时,合理利用聚合函数和针对分组字段的索引可以加速查询。例如,`CREATE INDEX idx_status ON orders(status); SELECT status, COUNT(*) AS total_orders FROM orders GROUP BY status;` 中,`idx_status` 索引帮助快速定位每个状态下的订单记录,从而减少分组操作的时间开销[^1]。 然而,分组字段查询的性能通常依赖于数据分布和索引的设计。如果分组字段的数据分布不均匀或索引选择不当,则可能导致性能下降。 #### 2. 多参数 `WHERE` 查询的效率分析 多参数 `WHERE` 查询的效率主要取决于以下几个因素: - **索引的选择性**:索引的选择性越高,查询效率越高。例如,在 `SELECT * FROM users WHERE name = 'John' AND age > 30` 中,如果 `name` 和 `age` 的组合具有较高的选择性,则可以通过联合索引 `(name, age)` 提高查询速度[^3]。 - **索引的使用顺序**:B-树索引必须遵循左边前缀原则,即查询必须从索引的最左边的列开始,并按照从左到右的顺序进行匹配。例如,对于联合索引 `(col1, col2, col3)`,查询条件可以是 `col1 = ?` 或 `col1 = ? AND col2 = ?`,但不能跳过 `col1` 直接使用 `col2` 或 `col3`[^3]。 - **查询条件的复杂性**:复杂的查询条件(如包含多个子查询或连接操作)可能会导致优化器无法有效利用索引。例如,`value IN (SELECT primary_key FROM single_table WHERE some_expr)` 可以通过 `unique_subquery` 优化为等价的 `eq_ref` 索引查找,但如果子查询返回的结果集过大,则可能影响性能[^2]。 #### 3. 示例代码与性能对比 以下是一个具体的例子,展示了不同查询方式的性能差异: ```sql -- 创建联合索引 CREATE INDEX idx_name_age ON users(name, age); -- 查询方式1:使用联合索引 SELECT name, email FROM users WHERE name = 'John' AND age > 30; -- 查询方式2:分组字段查询 CREATE INDEX idx_status ON orders(status); SELECT status, COUNT(*) AS total_orders FROM orders GROUP BY status; ``` 在上述例子中,查询方式1通过联合索引 `(name, age)` 实现了高效的过滤和数据检索,而查询方式2则通过针对分组字段 `status` 的索引加速了分组操作。 #### 4. 性能优化建议 - 对于频繁查询且数据量较小的场景,可以考虑将数据加载到内存表或临时表中进行操作,以减少磁盘 I/O 开销。 - 在大规模数据集上,可以通过数据分区或分片技术将数据分散到多个物理存储单元中,从而实现并行处理和提升查询性能[^4]。 - 使用物化视图预计算并存储复杂查询的结果,可以显著减少重复计算的开销。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值