从String中检索值的最快方法是什么?

时间:2021-07-09 01:37:48

During my app development one performance question came to my mind:

在我的应用开发期间,我想到了一个性能问题:

I have a lot of lines of data that can looks like that:

我有很多行数据可以看起来像这样:

  • !ANG:-0.03,0.14,55.31
  • !ANG:-0.03,-0.14,305.31
  • !ANG:-234.03,-0.14,55.31
  • in general: !ANG:float,float,float
  • 一般来说:!ANG:浮动,浮动,浮动

Between those lines there are also "damaged" lines - they don't start with ! or are too short/have extra signs and so on.

在这些线之间还有“损坏”线 - 它们不是从一开始!或者太短/有额外的迹象等等。

To detect lines that are damaged at the begining I simply use

为了检测在开始时损坏的线路,我只需使用

if(myString.charAt(0) != '!')//wrong string

What I can do to detect lines that are damaged at the end? It is very important to mention that I need not only to check if the line is correct but also get those 3 float numbers to use it later.

我能做些什么来检测最后损坏的线路?值得一提的是,我不仅要检查线路是否正确,还要获得这3个浮点数以便以后使用。

I've found three options for this:

我找到了三个选项:

  • use regexp
  • split twice (first ":" and second ",") and count elements
  • 拆分两次(第一个“:”和第二个“,”)和计数元素

  • use Scanner class
  • 使用Scanner类

I am not sure which one of this (or maybe there are other) methods will be the best from the performance point of view. Can you please give me some advice?

从性能的角度来看,我不确定这个(或者可能还有其他)方法中哪一个是最好的。你能给我一些建议吗?

EDIT:

After some comments I see that it is worth to write how damage lines an look:

经过一些评论后,我看到值得写一下损伤线的外观:

  • NG:-0.03,0.14,55.31
  • .14,55.31
  • !ANG:-0.03,0.14,
  • !A,-0.02,-0.14,554,-0.12,55

It is quite difficult to talk about number of lines because I am getting them from readings from other device so I get packets of around 20 lines at a time with a frequency of 50Hz.

谈论线路数量是非常困难的,因为我从其他设备的读数中得到它们,所以我一次得到大约20行的数据包,频率为50Hz。

What I've found out so far is the big drawback of using scanner - for each line I need to create new object and after some time my device is starting to get short on resources.

到目前为止我发现的是使用扫描仪的一大缺点 - 对于我需要创建新对象的每一行,一段时间后我的设备开始缺少资源。

2 个解决方案

#1


Benchmark them, then you will know.

对他们进行基准测试,然后你会知道。

The likely fastest way is to write your own tiny state machine to match your format and find the float boundaries. Theoretically a regex will have the same performance, but it's likely to have additional overhead.

可能最快的方法是编写自己的小型状态机以匹配您的格式并找到浮动边界。从理论上讲,正则表达式具有相同的性能,但可能会产生额外的开销。

#2


As an intermediate solution I'd do something like that :

作为一个中间解决方案,我会做这样的事情:

private static class LineObject {
    private float f1, f2, f3;
}

private LineObject parseLine(String line) {
    LineObject obj = null;
    if (line.startsWith("!ANG:")) {
        int i = line.indexOf(',', 5);
        if (i != -1) {
            int j = line.indexOf(',', i+1);
            if (j != -1) {
                try {
                    obj = new LineObject();
                    obj.f1 = Float.parseFloat(line.substring(5, i));
                    obj.f2 = Float.parseFloat(line.substring(i+1, j));
                    obj.f3 = Float.parseFloat(line.substring(++j));
                } catch (NumberFormatException e) {
                    return null;
                }
            }
        }
    }
    return obj;
}

After you can copy/paste only usefull jdk code of startsWith, indexOf and parseFloat in your own state machine...

在您自己的状态机中只能复制/粘贴startsWith,indexOf和parseFloat的有用jdk代码之后......

#1


Benchmark them, then you will know.

对他们进行基准测试,然后你会知道。

The likely fastest way is to write your own tiny state machine to match your format and find the float boundaries. Theoretically a regex will have the same performance, but it's likely to have additional overhead.

可能最快的方法是编写自己的小型状态机以匹配您的格式并找到浮动边界。从理论上讲,正则表达式具有相同的性能,但可能会产生额外的开销。

#2


As an intermediate solution I'd do something like that :

作为一个中间解决方案,我会做这样的事情:

private static class LineObject {
    private float f1, f2, f3;
}

private LineObject parseLine(String line) {
    LineObject obj = null;
    if (line.startsWith("!ANG:")) {
        int i = line.indexOf(',', 5);
        if (i != -1) {
            int j = line.indexOf(',', i+1);
            if (j != -1) {
                try {
                    obj = new LineObject();
                    obj.f1 = Float.parseFloat(line.substring(5, i));
                    obj.f2 = Float.parseFloat(line.substring(i+1, j));
                    obj.f3 = Float.parseFloat(line.substring(++j));
                } catch (NumberFormatException e) {
                    return null;
                }
            }
        }
    }
    return obj;
}

After you can copy/paste only usefull jdk code of startsWith, indexOf and parseFloat in your own state machine...

在您自己的状态机中只能复制/粘贴startsWith,indexOf和parseFloat的有用jdk代码之后......