Это решение работает с .NET Core 2.2. Он использует метод расширения без выделения на ReadOnlySpan
(SplitNext
).
public class Program {
public void MyAnswer() {
long machineId = 0;
long employeeId = 0;
var description = "machineId: 276744, engineId: 59440, employeeId: 4619825";
var span = description.AsSpan();
while (span.Length > 0) {
var entry = span.SplitNext(',');
var key = entry.SplitNext(':').TrimStart(' ');
var value = entry.TrimStart(' ');
if (key.Equals("machineId", StringComparison.Ordinal)) {
long.TryParse(value, out machineId);
}
if (key.Equals("employeeId", StringComparison.Ordinal)) {
long.TryParse(value, out employeeId);
}
}
}
}
public static class Extensions {
public static ReadOnlySpan SplitNext(this ref ReadOnlySpan span, char seperator) {
int pos = span.IndexOf(seperator);
if (pos > -1) {
var part = span.Slice(0, pos);
span = span.Slice(pos + 1);
return part;
} else {
var part = span;
span = span.Slice(span.Length);
return part;
}
}
}
Я сравнил ваш исходный код, существующий ответ и мой ответ через BenchmarkDotnet. Это показывает, что это решение действительно без выделения ресурсов и работает быстрее, чем оригинальная версия:
BenchmarkDotNet=v0.11.4, OS=Windows 10.0.17763.316 (1809/October2018Update/Redstone5)
Intel Core i5-2500K CPU 3.30GHz (Sandy Bridge), 1 CPU, 4 logical and 4 physical cores
.NET Core SDK=2.2.104
[Host] : .NET Core 2.2.2 (CoreCLR 4.6.27317.07, CoreFX 4.6.27318.02), 64bit RyuJIT
DefaultJob : .NET Core 2.2.2 (CoreCLR 4.6.27317.07, CoreFX 4.6.27318.02), 64bit RyuJIT
| Method | Mean | Error | StdDev | Gen 0/1k Op | Gen 1/1k Op | Gen 2/1k Op | Allocated Memory/Op |
|--------- |-----------:|----------:|----------:|------------:|------------:|------------:|--------------------:|
| Original | 1,164.1 ns | 11.606 ns | 10.289 ns | 0.2937 | - | - | 928 B |
| Answer | 460.5 ns | 4.527 ns | 4.234 ns | - | - | - | - |
| MyAnswer | 445.7 ns | 2.578 ns | 2.412 ns | - | - | - | - |
Помимо оптимизации обработки строк, фактическая функция синтаксического анализа также может быть оптимизирована. Это будет более быстрый анализатор длинных строк:
public static long LongParseFast(ReadOnlySpan value) {
long result = 0;
for (int i = 0; i < value.Length; i++) {
result = 10 * result + (value[i] - 48);
}
return result;
}
Если использовать его в моем примере, он удваивает производительность до 216.0 ns
в моих тестах. Конечно, эта функция не может иметь дело с такими вещами, как отрицательные числа, запятые, точки и другие локали. Но если вы в порядке с этим, это, вероятно, так быстро, как вы можете.
альтернативно Вы могли записать webservice/xmlrpc слой между двумя.
я, кажется, помню, что существует кузнечик вызовов инструмента, который скомпилирует Ваш код.Net в байт-код JVM.
я также услышал хорошие вещи о IKVM
Это является действительно потрясающим. Единственная проблема состоит в том, что это ДЕЙСТВИТЕЛЬНО добавляет ~30MB к проекту. log4net и.NET Spring доступны также, но при проживании с существующим кодом, идут ikvm путем.
Я являюсь автором jni4net , межпроцессного моста с открытым исходным кодом между JVM и CLR. Он построен на базе JNI и PInvoke. Код C / C ++ не требуется. Надеюсь, это вам поможет.