六大质量属性以——以“信息领域热词分析系统”为例性能代码分析

性能战术的目标:对一定时间限制内到达系统的事件生成一个响应,这些事件可以是消息到达、定时器到时,系统状态的变化。

 

 性能战术的分类以及基本的方法

 

 

资源需求:

需求具有两个特性:资源流中事件之间的时间间隔;每个请求所消耗的资源

1.减少一个事件流所用的资源

(1)提高计算效率,如改进关键算法

比如在数据查找时采用二分查找法可以大大减少查找时间

(2)减少计算开销

比如保留上次计算结果

2.减少处理事件的数量,减小频率。

(1)管理事件率

(2)控制采样频率

3.控制资源的使用

(1)限制执行时间

(2)限制队列大小

结合以上总结,首先我认为可以改进自我代码的算法如:

二分查找法:

public int getPos(int[] A, int n, int val) {
        // write code here
        if (n <= 0) {//如果数组长度为0
            return -1;
        }
        if (n == 1) {//如果数组长度为1
           if (A[0] == val) {
               return 0;
           }else {
               return -1;
           }
         }
        int left = 0;//左侧索引
        int right = n-1;//右侧索引
        int mid = 0;
        while (left <= right) {//注意这里是小于等于
            mid = left + (right-left)/2;//取中间的值
            if (val == A[mid]) {//如果相等,则返回索引位置
                return mid;
            }else if (val > A[mid]){ //如果大于,则选择右边半部分继续比较
                    left = mid+1;
            }else{//如果小于,则选择左边半部分继续比较
                    right = mid-1;
                }
        }
        return -1;
    }

或者减少事件数量、减少频率或者限制队列大小或者限制时间

限制队列大小我个人觉得应该处理在于数据库方面,比如我只差某个时间段的热词,只对该时间段进行分析,数量就可大大减少,那么就可以根据时间进行数据排查筛选分析

或者也可以限制时间

比如

public static void main(String[] args) throws InterruptedException,  
        ExecutionException {  
      
    final ExecutorService exec = Executors.newFixedThreadPool(1);  
      
    Callable<String> call = new Callable<String>() {  
        public String call() throws Exception {  
            //开始执行耗时操作  
            Thread.sleep(1000 * 5);  
            return "线程执行完成.";  
        }  
    };  
      
    try {  
        Future<String> future = exec.submit(call);  
        String obj = future.get(1000 * 2, TimeUnit.MILLISECONDS); //任务处理超时时间设为 2 秒  
        System.out.println("任务成功返回:" + obj);  
    } catch (TimeoutException ex) {  
        ex.printStackTrace();  
    } catch (Exception e) {  
        System.out.println("处理失败.");  
        e.printStackTrace();  
    }  
    // 关闭线程池  
    exec.shutdown();  

 

限制队列大小

比如Queue

Queue: 基本上,一个队列就是一个先入先出(FIFO)的数据结构

Queue的实现

1、没有实现的阻塞接口的LinkedList: 实现了java.util.Queue接口和java.util.AbstractQueue接口

2.实现阻塞接口的:
  java.util.concurrent 中加入了 BlockingQueue 接口和五个阻塞队列类。它实质上就是一种带有一点扭曲的 FIFO 数据结构。不是立即从队列中添加或者删除元素,线程执行操作阻塞,直到有空间或者元素可用。

例如

public static class Basket{
  // 篮子,能够容纳3个苹果
  BlockingQueue<String> basket = new ArrayBlockingQueue<String>(3);

  // 生产苹果,放入篮子
  public void produce() throws InterruptedException{
   // put方法放入一个苹果,若basket满了,等到basket有位置
   basket.put("An apple");
  }
  // 消费苹果,从篮子中取走
  public String consume() throws InterruptedException{
   // get方法取出一个苹果,若basket为空,等到basket有苹果为止
   String apple = basket.take();
   return apple;
  }

  public int getAppleNumber(){
   return basket.size();
  }

 }
 // 测试方法
 public static void testBasket() {
  // 建立一个装苹果的篮子
  final Basket basket = new Basket();
  // 定义苹果生产者
  class Producer implements Runnable {
   public void run() {
    try {
     while (true) {
      // 生产苹果
      System.out.println("生产者准备生产苹果:" 
        + System.currentTimeMillis());
      basket.produce();
      System.out.println("生产者生产苹果完毕:" 
        + System.currentTimeMillis());
      System.out.println("生产完后有苹果:"+basket.getAppleNumber()+"个");
      // 休眠300ms
      Thread.sleep(300);
     }
    } catch (InterruptedException ex) {
    }
   }
  }
  // 定义苹果消费者
  class Consumer implements Runnable {
   public void run() {
    try {
     while (true) {
      // 消费苹果
      System.out.println("消费者准备消费苹果:" 
        + System.currentTimeMillis());
      basket.consume();
      System.out.println("消费者消费苹果完毕:" 
        + System.currentTimeMillis());
      System.out.println("消费完后有苹果:"+basket.getAppleNumber()+"个");
      // 休眠1000ms
      Thread.sleep(1000);
     }
    } catch (InterruptedException ex) {
    }
   }
  }

  ExecutorService service = Executors.newCachedThreadPool();
  Producer producer = new Producer();
  Consumer consumer = new Consumer();
  service.submit(producer);
  service.submit(consumer);
  // 程序运行10s后,所有任务停止
  try {
   Thread.sleep(10000);
  } catch (InterruptedException e) {
  }
  service.shutdownNow();
 }
 public static void main(String[] args) {
  BlockingQueueTest.testBasket();
 }

  

资源管理:

1.引入并发

2.维持数据或计算的多个副本

3.增加可用资源

这个受硬件影响较大

 

资源仲裁

当程序对资源争用的时候,进行相关的资源调度,以使资源协调一致的运行,以减少闭锁时间。

1.先进先出,同等看待每个资源

2.固定优先级,事先为某个事件分配优先级

3.动态优先级,运行时分配优先级

4.静态调度,非运行时确定资源的分配顺序

package com.first;

public class ThreadPriority
{
    public static void main(String[] args) {

        System.out.println(Thread.currentThread().getName()
                +"("+Thread.currentThread().getPriority()+ ")");

        Thread t1=new ThreadP("thread1");    // 新建t1
        Thread t2=new ThreadP("thread2");    // 新建t2
        t1.setPriority(5);               // 设置t1的优先级为1
        t2.setPriority(5);              // 设置t2的优先级为10
        t1.start();                      // 启动t1
        t2.start();                      // 启动t2
    }

}
class ThreadP extends Thread{

    public ThreadP(String name) {
        super(name);
    }

    public void run(){
        for (int i=0; i<5; i++) {
            System.out.println(Thread.currentThread().getName()
                    +"("+Thread.currentThread().getPriority()+ ")"
                    +", loop "+i);
        }
    }

}

 

参考:Java队列————quene详细分析https://www.cnblogs.com/lemon-flm/p/7877898.html

 

posted @ 2020-03-02 22:01  暗梦  阅读(205)  评论(0编辑  收藏  举报