В .NET Substring
- это O (n), а не O (1) в Java. Это связано с тем, что в .NET объект String сам содержит все фактические символьные данные 1 , поэтому взятие подстроки предполагает копирование всех данных в новой подстроке. В Java substring
может просто создать новый объект, ссылающийся на исходный массив символов, с другим начальным индексом и длиной.
Есть плюсы и минусы каждого подхода:
- . Подход .NET имеет лучшую когерентность кэша, создает меньше объектов 2 и избегает ситуации, когда одна маленькая подстрока предотвращает сбор очень большого
char[]
мусора. Я верю, что в некоторых случаях это может сделать взаимодействие очень легким, внутренне.
- Подход Java делает подстроку очень эффективной, и, возможно, некоторые другие операции тоже
В моей статье strings .
есть немного больше деталей.
Что касается общего вопроса о том, как избежать ошибок в производительности, я думаю, у меня должен быть готовый ответ, готовый вырезать и вставлять: убедитесь, что ваша архитектура эффективна, и реализуйте ее наиболее читабельным способом , Измеряйте производительность и оптимизируйте места, где вы найдете узкие места.
1 Кстати, это делает string
очень особенным - это единственный тип, не относящийся к массиву, объем памяти которого зависит от экземпляра в пределах одного и того же CLR.
2 Для маленьких струн это большая победа. Достаточно плохо, что есть все издержки одного объекта, но если задействован также дополнительный массив, односимвольная строка может занимать около 36 байт в Java. (Это число «палец в воздухе» - я не могу вспомнить точные накладные расходы на объект. Это также будет зависеть от используемой виртуальной машины.)