以%.7f格式创建时间戳字符串的更快方法

问题描述:

这是一个函数,我必须以%.7f格式创建时间戳字符串。该功能只需要2-3毫秒即可执行。但是从我的代码中的很多地方调用它,甚至通过1 ms优化它,我将在一个特定用户操作中节省1秒。有任何想法吗?以%.7f格式创建时间戳字符串的更快方法

public static String makeTimestamp() 
{ 
    long millis = System.currentTimeMillis(); 
    String result; 
    Double ts = new Double((millis)/1000.0); 

    ByteArrayOutputStream b = new ByteArrayOutputStream(); 
    PrintStream p = new PrintStream(b); 
    p.printf("%.7f", ts); 
    result = b.toString(); 
    try 
    { 
     p.close(); 
     b.close(); 
    } catch (IOException ioe) {}; 
    return result; 
} 
+0

评估的三个答案(在评估时),这些都是与时俱进,在nanoSecs'原文:2691355 选项1:82347 选项2:87703 选项3:20754'。正如你可以看到选项3(char [] implmentation)要快得多。但我倾向于选择2,因为我确信我的软件将在2286年运行;) – Nishan 2011-03-18 11:33:04

+1

我同意保持简单,除非您真的需要它更快,所以较短的答案可能是最适合您的。尽管我看到了自己喜欢挑战的方式,但是我继续修正了我的版本,以支持2286年以后的版本。要正确地对待选项,您需要重复至少几千次,以查看JIT生效后它的差异。我仍然在Java 6 Update 24上显示速度提高了10倍。 – WhiteFang34 2011-03-18 12:05:00

如果你绝对需要它,这是不是字符串格式化快约10倍:

public static String makeTimestamp() { 
    return formatTime(System.currentTimeMillis(), 7); 
} 

public static String formatTime(long millis, int fractionDigits) { 
    int integerDigits = (int) Math.log10(millis/1000.0) + 1; 

    char[] chars = new char[integerDigits + fractionDigits + 1]; 
    for (int i = 0; i < chars.length; i++) { 
     chars[i] = '0'; 
    } 

    millis *= Math.pow(10, fractionDigits - 3); 
    for (int i = chars.length - 1; i >= 0; i--) { 
     if (i == integerDigits) { 
      chars[i] = '.'; 
      i--; 
     } 

     chars[i] = (char) (millis % 10); 
     chars[i] += '0'; 

     millis /= 10; 
    } 

    return new String(chars); 
} 
+1

+1,现在将其作为注释添加到代码中,以便在有人将其复制并粘贴到代码库(我确信会发生这种情况)时保留它。 – 2011-03-18 07:47:21

+0

@Joachim:好点,我将笔记移动到代码注释中,以便在人们复制和粘贴时保留它们 – WhiteFang34 2011-03-18 07:54:11

+0

已更新我的代码以支持过去2286年和小数点后的可变数字位数。 – WhiteFang34 2011-03-18 12:01:17

我不知道它是如何更快,但如何

public static String makeTimestamp() 
{ 
    return String.format("%.7f", ((double)System.currentTimeMillis())/1000); 
} 

(和我不知道为什么我们把双入图片)。

这不是完全清楚为什么你正在经历一个PrintStream等出了什么问题:

public static String makeTimestamp() 
{ 
    long millis = System.currentTimeMillis(); 
    return String.format("%.7f", millis/1000.0); 
} 

在我的上网本那大约需要每次迭代0.04ms ......但即使你原来的代码只需要每次迭代大约0.1ms。你现在在跑2-3毫米的时间?例如,你在调试器中运行吗?我不明白为什么会这么慢 - 这不像我的上网本是一个特别快的机器。

虽然所有的性能都很重要,但我认为上述方法的主要优点是简单。原来是非常复杂的,没有任何理由。

+0

我的机器在FreeBSD上运行Sun JVM 1.5。可能不同的平台/ jvms可以更高效地执行此操作,但我尚未进行测试。 – Nishan 2011-03-21 05:21:37

+0

@Nishan:你使用'System.currentTimeMillis'测试了*吗?这可能是瓶颈。 – 2011-03-21 06:25:35