【问题标题】:Which is efficient in terms of memory: char[] or String?哪个在内存方面有效:char[] 还是 String?
【发布时间】:2023-04-09 13:47:01
【问题描述】:

我正在开发一个 Android 应用程序。应用程序的主要要求是它在内存方面应该是高效的。那么,我应该选择哪一个呢?

String batterylevel;
batterylevel = Float.toString(batteryPct);

char batterylevel[];
batterylevel = Float.toString(batteryPct).toCharArray();

【问题讨论】:

  • 您多久检查一次电池电量,这样每次检查约 16 个字节会产生明显差异?
  • 有一个刷新按钮可以刷新电池电量。所以,这完全取决于用户。不过,没有明显的区别。
  • Android 系统可能分配了更多的内存,只是为了在用户单击按钮时使按钮变为橙色。您对内存使用的关注程度如何? (而当 Android 应用程序出现内存问题时,通常是由于加载了 兆字节 的图像)
  • 嗯,我只关心 20 个字符串。我认为每当创建 String 类的对象时也会分配实例变量。 20 个这样的案例会产生巨大的影响吗?
  • 每个字符串 3 个额外的 int 字段(32 位)+ 1 个引用(64 位)= 12+8 = 20。20 * 20 = 额外 400 个字节。您将节省惊人的 0.0004 兆字节。我认为您正在寻求优化一些根本不值得的东西。还要注意 toCharArray 调用创建了原始字符串内部缓冲区的副本。这意味着只要垃圾收集器不会释放您实际使用更多内存的内存(阅读:双倍内存)。我建议你只使用 String 方法。

标签: java android arrays string


【解决方案1】:

在 Oracle 的 JDK 中,String 有四个实例级字段:

  • 一个字符数组
  • 积分偏移
  • 整数字符计数
  • 整数哈希值

这意味着每个字符串都引入了一个额外的对象引用(字符串本身),以及除了字符数组本身之外的三个整数。 (偏移量和字符数允许在通过 String#substring() 方法生成的 String 实例之间共享字符数组,这是其他一些 Java 库实现者避免的设计选择。)除了额外的存储成本之外,还有一个更高级别的间接访问,更不用说 String 保护其字符数组的边界检查了。

字符串是不可变的。这意味着一旦您创建了字符串,如果另一个进程可以转储内存,那么(除了反射之外)您无法在 GC 启动之前摆脱数据,这意味着浪费内存。

使用数组,您可以在完成后显式擦除数据:您可以用任何您喜欢的内容覆盖数组。

据我所知,就您的情况而言,char[] 在内存方面更好。

【讨论】:

    【解决方案2】:

    String 是 java 中的类,它包装了 char 数组,正如您在代码中看到的那样

    private final char value[];
    

    因此,每次创建 String 对象时,它都由 char 数组支持。 而且 String 类也有三个不同的字段,因为它比 char 数组占用更多的内存。

    但是如果您看到用法,那么 String 比 char 数组更好,因为它是不可变的。您不必对 String 进行任何内存管理。性能明智的 char array[] 对于少数操作(如果您正在处理大量数据)更快。

    【讨论】:

      【解决方案3】:

      除了字符数组(或宽字符)之外,CString 还包含字符串大小、分配的缓冲区大小和引用计数器(另外用作锁定标志)。包含字符数组的缓冲区可能比它包含的字符串大得多——它可以减少耗时的分配调用的数量。另外,当 CString 设置为零大小时,它仍然包含两个 wchar 字符。

      自然地,当你将 CString 的大小与对应的 C 样式数组的大小进行比较时,数组会更小。但是,如果您想在 CString 允许的范围内尽可能广泛地操作您的字符串,您最终会为字符串大小、缓冲区大小以及有时 refcounter 和/或保护标志定义自己的变量。实际上,您需要存储字符串大小以避免每次需要时都调用 strlen。如果允许缓冲区大于字符串长度,则需要单独存储缓冲区大小,并避免在每次添加或减去字符串时调用 reallocs。依此类推——你用一些小尺寸的增加换取速度、安全性和功能的显着增加。

      所以,答案取决于你要对字符串做什么。假设您想要一个字符串来存储类的名称以进行日志记录——C 风格的字符串(const 和 static)就可以了。如果您需要一个字符串来操作它并将其广泛用于与 MFC 或 ATL 相关的类,请使用 CString 系列类型。如果您需要在应用程序的“引擎”部分中操作与其接口隔离的字符串,并且可能会转换到其他平台,请使用 std::string 或编写您自己的字符串类型以满足您的特定需求(这可以是当您编写“胶水”代码放置在接口和引擎之间时非常有用,否则最好使用 std::string)。

      P.S 比较 C++ 的字符串与 char[]

      Source

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-13
        • 2013-03-24
        • 2012-12-05
        • 2014-06-24
        • 1970-01-01
        • 1970-01-01
        • 2022-01-02
        • 2010-10-08
        相关资源
        最近更新 更多