Slf4j 简明教程

SLF4J - Profiling

SLF4J 分发提供 slf4j-ext.jar 这里包含用于分析性能、扩展记录、事件记录和使用 Java 代理记录等功能的 API。

SLF4J Distribution provides slf4j-ext.jar this contains APIs for the functionalities such as profiling, Extended logging, Event logging and, logging with java agent.

Profiling

有时,程序员想要测量一些属性,如内存使用、时间复杂度或特定指令的使用,以测量该程序的实际能力。对此类程序的测量称为分析性能。分析性能使用动态程序分析进行测量。

Sometimes the programmer wants to measure some attributes like the use of memory, time complexity or usage of particular instructions about the programs to measure the real capability of that program. Such kind of measuring about the program is called profiling. Profiling uses dynamic program analysis to do such measuring.

SLF4J 提供名为 Profiler 的类,位于 org.slf4j.profiler 包中,用于性能分析。这被称为穷人的分析程序。使用此类,程序员可以找出执行较长时间任务所花费的时间。

SLF4J provides a class named Profiler in the org.slf4j.profiler package for profiling purpose. This is known as the poor man’s profiler. Using this, the programmer can find out the time taken to carry out prolonged tasks.

Profiling Using the Profiler class

分析性能包含秒表和子秒表,我们可以使用分析性能类提供的方法来启动和停止它们。

The profiler contains stopwatches and child stopwatches and we can start and stop these using the methods provided by the profiler class.

若要通过 Profiler 类继续进行分析,请按照以下步骤操作。

To carry on with profiling using the profiler class, follow the steps given below.

Step 1 - Instantiate the profiler class

通过传递表示分析器名称的 String 值来实例化 Profiler 类。实例化 Profiler 类时,将启动全局秒表。

Instantiate the Profiler class by passing a String value representing the name of the profiler. When we instantiate a Profiler class, a global stopwatch will be started.

//Creating a profiler
Profiler profiler = new Profiler("Sample");

Step 2 - Start a child stopwatch

调用 start() 方法时,将启动一个新的子秒表(命名),并停止较早的子秒表(或时间工具)。

When we invoke the start() method it will start a new child stopwatch (named) and, stops the earlier child stopwatches (or, time instruments).

通过传递表示要创建的子秒表名称的 String 值来调用 Profiler 类的 start() 方法。

Invoke the start() method of the Profiler class by passing a String value representing the name of the child stopwatch to be created.

//Starting a child stopwatch and stopping the previous one.
profiler.start("Task 1");
obj.demoMethod1();

创建这些秒表后,您可以执行您的任务或调用运行您任务的方法。

After creating these stopwatches, you can perform your tasks or, invoke those methods, which run your tasks.

Step 3: Start another child stopwatch (if you wish to)

如果您需要,请使用 start() 方法创建另一个秒表并执行所需的任务。如果您这样做,它将启动一个新的秒表并停止前一个秒表(即任务 1)。

If you need, create another stopwatch using the start() method and perform the required tasks. If you do so, it will start a new stop watch and stops the previous one (i.e. task 1).

//Starting another child stopwatch and stopping the previous one.
profiler.start("Task 2");
obj.demoMethod2();

Step 4: Stop the watches

当我们调用 stop() 方法时,它将停止最近的子秒表和全局秒表并返回当前时间工具。

When we invoke the stop() method, it will stop the recent child stopwatch and the global stopwatch and returns the current Time Instrument.

// Stopping the current child stopwatch and the global stopwatch.
TimeInstrument tm = profiler.stop();

Step 5: Print the contents of the time instrument.

使用 print() 方法打印当前时间工具的内容。

Print the contents of the current time instrument using the print() method.

//printing the contents of the time instrument
tm.print();

Example

以下示例演示了使用 SLF4J 的 Profiler 类的分析。这里我们取了两个示例任务,打印从 1 到 10000 的数字的平方和,打印从 1 到 10000 的数字的和。我们正尝试获得这两个任务所需的时间。

The following example demonstrates the profiling using Profiler class of SLF4J. Here we have taken two sample tasks, printing the sum of squares of the numbers from 1 to 10000, printing the sum of the numbers from 1 to 10000. We are trying to get the time taken for these two tasks.

import org.slf4j.profiler.Profiler;
import org.slf4j.profiler.TimeInstrument;

public class ProfilerExample {
   public void demoMethod1(){
      double sum = 0;
      for(int i=0; i< 1000; i++){
         sum = sum+(Math.pow(i, 2));
      }
      System.out.println("Sum of squares of the numbers from 1 to 10000: "+sum);
   }
   public void demoMethod2(){
      int sum = 0;
      for(int i=0; i< 10000; i++){
         sum = sum+i;
      }
      System.out.println("Sum of the numbers from 1 to 10000: "+sum);
   }
   public static void main(String[] args) {
      ProfilerExample obj = new ProfilerExample();

      //Creating a profiler
      Profiler profiler = new Profiler("Sample");

      //Starting a child stop watch and stopping the previous one.
      profiler.start("Task 1");
      obj.demoMethod1();

      //Starting another child stop watch and stopping the previous one.
      profiler.start("Task 2");
      obj.demoMethod2();

      //Stopping the current child watch and the global watch.
      TimeInstrument tm = profiler.stop();

      //printing the contents of the time instrument
      tm.print();
   }
}

Output

执行后,上述程序生成以下输出 -

Upon execution, the above program generates the following output −

Sum of squares of the numbers from 1 to 10000: 3.328335E8
Sum of the numbers from 1 to 10000: 49995000
+ Profiler [BASIC]
|-- elapsed time [Task 1] 2291.827 microseconds.
|-- elapsed time [Task 2] 225.802 microseconds.
|-- Total [BASIC] 3221.598 microseconds.

Logging the Profiler Information

与其将分析器结果打印到日志中以记录此信息,您需要 -

Instead of printing the result of a profiler to log this information, you need to −

  1. Create a logger using the LoggerFactory class.

  2. Create a profiler by instantiating the Profiler class.

  3. Associate the logger to profiler by passing the logger object created to the setLogger() method of the Profiler class.

  4. Finally, instead of printing log the information of the profiler using the log() method.

Example

在以下示例中,与前一个示例不同(而非打印),我们尝试记录时间工具的内容。

In the following example, unlike the previous one (instead of printing), we are trying to log the contents of the time instrument.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.profiler.Profiler;
import org.slf4j.profiler.TimeInstrument;

public class ProfilerExample_logger {
   public void demoMethod1(){
      double sum = 0;
      for(int i=0; i< 1000; i++){
         sum = sum+(Math.pow(i, 2));
      }
      System.out.println("Sum of squares of the numbers from 1 to 10000: "+sum);
   }
   public void demoMethod2(){
      int sum = 0;
      for(int i=0; i< 10000; i++){
         sum = sum+i;
      }
      System.out.println("Sum of the numbers from 1 to 10000: "+sum);
   }
   public static void main(String[] args) {
      ProfilerExample_logger obj = new ProfilerExample_logger();

      //Creating a logger
      Logger logger = LoggerFactory.getLogger(ProfilerExample_logger.class);

      //Creating a profiler
      Profiler profiler = new Profiler("Sample");

      //Adding logger to the profiler
      profiler.setLogger(logger);

      //Starting a child stop watch and stopping the previous one.
      profiler.start("Task 1");
      obj.demoMethod1();

      //Starting another child stop watch and stopping the previous one.
      profiler.start("Task 2");
      obj.demoMethod2();

      //Stopping the current child watch and the global watch.
      TimeInstrument tm = profiler.stop();

      //Logging the contents of the time instrument
      tm.log();
   }
}

Output

执行后,上述程序生成以下输出。

Upon execution, the above program generates the following output.

Sum of squares of the numbers from 1 to 10000: 3.328335E8
Sum of the numbers from 1 to 10000: 49995000