简体   繁体   English

使用Java进行多少处理和内存使用?

[英]How much processing and memory use does casting take in Java?

I am considering whether it is better to have two pointers, one for each object sub class and super, or whether I should just use casting. 我正在考虑是否有两个指针更好,每个对象子类和超级一个,或者我是否应该使用强制转换。

How much system resources does this use: 这使用了多少系统资源:

objectName.functionOne();
((SubClass) objectName).functionOther();

Is it better than: 它比以下更好:

SuperClass objectA = (SuperClass) getSameInstance();
SubClass objectB = getSameInstance();
objectA.functionOne();
objectB.functionOther();

Basically, my main question is about the resources used with casting, versus making an extra pointer. 基本上,我的主要问题是关于使用铸造的资源,而不是制作额外的指针。 It seems like I could save several in line casts, such as: 看起来我可以保存几个在线演员阵容,例如:

((SubClass) objectName).functionOther();

However, is it worth it? 但是,值得吗?

Thanks, 谢谢,
Grae GRAE

UPDATE: 更新:

There were some unclear parts to my question. 我的问题有一些不清楚的部分。 Basically, I have a super class that I am using through out a large function. 基本上,我有一个超级类,我通过一个大功能使用。 It works with three subclasses. 它适用于三个子类。 Some the super class is working as I would like. 有些超级班级正在按照我的意愿行事。 However, I hit a road block in a few places where I have to use a function from one of the three different subclass; 但是,我在一些地方碰到了路障,我必须使用三个不同子类中的一个来完成一个功能; a function that is only in one of the subclasses. 仅在其中一个子类中的函数。

I could just have: 我可能只有:

SuperClass instanceRef;
SubClass instanceRef2;

instanceRef.etc()
instanceRef.etc2()
instanceRef.etc3()
instanceRef2.specialSubClassOnlyCall();
instanceRef2.specialSubClassOnlyCall2();

or I could have: 或者我可以:

SuperClass instanceRef;

instanceRef.etc()
instanceRef.etc2()
instanceRef.etc3()
((SpecialSubClass)instanceRef).specialSubClassOnlyCall();
((SpecialSubClass)instanceRef).specialSubClassOnlyCall2();

However, I don't know which is more efficient. 但是,我不知道哪个更有效率。

UPDATE 2: 更新2:

Here is an example to show you what I am talking about: 这是一个例子,向您展示我在说什么:

class Shape
Triangle extends Shape
Square extends Shape
Circle extends Shape
Cube extends Shape

The Two Pointer Example: (Downside an extra pointer.) 两个指针示例:(缩小额外指针。)

Shape pointer1 = (Shape) getSomeRandomShape();
Cube pointer2 = null;

pointer1.getWidth();
pointer1.getHeight();
pointer1.generalShapeProp();
pointer1.generalShapeProp2();
pointer1.generalShapeProp3();

if(sure_its_cube)
{
   pointer2 = (Cube) pointer1;
   pointer2.getZAxis();
   pointer2.getOtherCubeOnlyThing();
   pointer2.getOtherCubeOnlyThing2();
   pointer2.getOtherCubeOnlyThing3();
   pointer2.getOtherCubeOnlyThing4();
}

Or I could do it this way. 或者我可以这样做。 (Downside a bunch of casts.) (下面是一堆演员。)

Shape pointer1 = (Shape) getSomeRandomShape();

pointer1.getWidth();
pointer1.getHeight();
pointer1.generalShapeProp();
pointer1.generalShapeProp2();
pointer1.generalShapeProp3();

if(sure_its_cube)
{
   ((Cube)pointer1).getZAxis();
   ((Cube)pointer1).getOtherCubeOnlyThing();
   ((Cube)pointer1).getOtherCubeOnlyThing2();
   ((Cube)pointer1).getOtherCubeOnlyThing3();
   ((Cube)pointer1).getOtherCubeOnlyThing4();
}

So is five casts worse than one extra pointer? 那么五个演员比一个额外的指针更差吗? What is it was six casts, or 20? 什么是六个演员,或20? Is one cast worse than the pointer. 是一个演员比指针差。

Grae GRAE

做任何使代码更清晰的事情,忘记微优化。

It seems from your code snippet that getSameInstance() returns a SubClass . 从您的代码片段可以 getSameInstance()getSameInstance()返回一个 SubClass In this case the simplest solution is 在这种情况下,最简单的解决方案是

 
 
 
  
  SubClass objectB = getSameInstance(); objectB.functionOne(); objectB.functionOther();
 
  

No casts, no worries :-) 没有演员阵容,没有后顾之忧:-)

As others have rightly noted, the primary concern should be code readability and simplicity, not performance. 正如其他人正确指出的那样,主要关注的应该是代码可读性和简单性,而不是性能。 Optimize only when you know that you need to, and have proven (using a profiler) where the bottleneck is within your code. 只有当您知道自己需要时才进行优化,并且已经证明(使用分析器)代码中存在瓶颈 Even in this case, micro-optimization is rarely useful in Java. 即使在这种情况下,微优化在Java中也很少有用。

An additional note: calling the same method twice can be problematic if the method is heavy (in which case you are effectively making your code slower, not faster), or has side effects (in which case the behaviour of your program may noticeably change). 另外注意:如果方法很重(在这种情况下,你有效地使你的代码变慢,而不是更快),或者有副作用(在这种情况下你的程序的行为可能会明显改变),调用相同的方法两次可能会有问题。

And btw in this line of your code snippet 顺便提一下你的代码片段

SuperClass objectA = (SuperClass) getSameInstance();

there is absolutely no need to upcast the returned value to SuperClass - a superclass reference can always point to a subclass object. 绝对没有必要将返回值向上转换为SuperClass - 超类引用总是可以指向子类对象。 (I guess that such an upcast would be omitted by the compiler anyway, so it makes no difference in the bytecode.) (我想无论如何编译器都会忽略这样的upcast,所以它在字节码中没有区别。)

Update 更新

You still haven't published the declaration of the method I asked for. 你还没有发表我要求的方法的声明。 But from your explanation I presume it should look something like 但根据你的解释,我认为它应该看起来像

public Shape getSomeRandomShape();

is this correct? 它是否正确?

This would btw mean that your 2nd original code snippet (with the getSameInstance() call) is incorrect - the casts should be the opposite way. 这将意味着你的第二个原始代码片段(带有getSameInstance()调用)不正确 - 强制转换应该是相反的方式。 You managed to confuse me with it, so you got a confusing answer :-) 你设法让我迷惑了,所以你有一个令人困惑的答案:-)

Also in the latest examples, you don't need to cast the returned value to a (Shape) , since it is already a Shape . 同样在最新的示例中,您不需要将返回值强制转换为(Shape) ,因为它已经是Shape The cast is just cluttering your code. 演员阵容让你的代码变得混乱。 Similarly, the many casts in the 2nd example of your UPDATE 2 are making the code hard to read. 同样,UPDATE 2的第二个示例中的许多强制转换使代码难以阅读。 I would prefer the first version, with two references ( not pointers btw - Java has no pointers). 我更喜欢第一个版本,有两个引用( 不是指针btw - Java没有指针)。

And I care only about code readability here - as others have already noted, you should really, really not waste your time thinking about the cost of casts . 我只关心这里的代码可读性 - 正如其他人已经注意到的那样, 你真的应该浪费你的时间来考虑演员阵容的成本 Just focus on making your code as simple and readable as possible . 只需专注于使您的代码尽可能简单易读 You would most likely never ever going to notice the tiniest bit of difference between the performance of the two code snippets you show above (unless maybe if they are executed in a tight loop millions of times - but then, I guess, the JIT would optimize the casts away anyway). 您很可能永远不会注意到您在上面显示的两个代码片段的性能之间的微小区别(除非他们在紧密循环中执行数百万次 - 但是,我猜,JIT会优化无论如何都被抛弃了)。 However, you will notice the difference it takes in time to understand one code snippet versus the other, for someone who is new to this code - or someone who has forgotten the details already, which could be you in about 6 months. 但是,您会注意到理解一个代码段与另一个代码段之间的差异,对于不熟悉此代码的人 - 或者已经忘记了详细信息的人,可能是您在大约6个月内。

Casting is not an "operation" that is done at runtime. 转换不是在运行时完成的“操作”。 It's just needed by the compiler to assure you static type safety. 编译器只需要确保静态类型安全。

Just looked at JVM code, the two approaches are basically equivalent, they are implemented as 刚看了JVM代码,这两种方法基本相同,它们实现为

CHECKCAST Main$B
INVOKEVIRTUAL Main$B.mySubMethod()V

so a small overhead is present, but it's the same in both cases (since you gotta do a downcast anyway). 因此存在一个小的开销,但在两种情况下都是相同的(因为你无论如何都要做一个向下转换)。

Readability and code maintenance should be your priority in something like this, not performance, unless you actually hit a bottleneck (extremely unlikely). 可读性和代码维护应该是这样的优先事项,而不是性能,除非你真正遇到瓶颈(极不可能)。

However, there is no reason to have two references (pointers). 但是,没有理由有两个引用(指针)。 Just reference the subclass. 只需引用子类。 Anything you could do with the superclass reference you can do with the subclass reference, in almost all cases (a parameter to an overloaded method is the only exception I know of). 在几乎所有情况下,您可以使用子类引用对超类引用执行任何操作(重载方法的参数是我所知道的唯一例外)。

Just go with whichever solution is easier to read and cleanest to maintain (likely the first solution). 只需使用更易于阅读的解决方案,并保持最清洁(可能是第一个解决方案)。 At that low a level of optimization, it's really not worth it except in edge cases where you really need the extra 0.01% performance improvement. 在这么低的优化水平下,除了在你真正需要额外0.01%性能提升的边缘情况下,它真的不值得。

For what it's worth, you don't actually need to cast a subclass to a superclass reference (second solution listed), only the other way around. 对于它的价值,你实际上并不需要将子类强制转换为超类引用(列出的第二个解决方案),只是反过来。 When casting a superclass to a subclass, it's generally preferred verify its type with instanceof prior to the cast rather than making assumptions. 在将超类强制转换为子类时,通常首选在强制转换之前使用instanceof验证其类型,而不是进行假设。

Lets say you have a 64-bit machine and it saves 8-bytes of resources. 假设您有一台64位计算机,它可以节省8个字节的资源。 Lets say you have spent 10 minutes think about it. 让我们说你花了10分钟考虑一下。 Was it a good use of your time? 这是好用的时间吗?

1 GB adds about $100 to the cost of a server so 8 bytes cost about $0.0000008 1 GB增加了大约100美元的服务器成本,因此8字节的成本约为0.0000008美元

10 minutes of you time is worth about $1 on minimum wage. 10分钟的时间最低工资价值约1美元。

The resource is reusable, your time is not. 资源是可重用的,你的时间不是。 More importantly the time of anyone reading/ supporting your code is likely to be even more expensive and that is why simplicity/clarity is far more important. 更重要的是,任何人阅读/支持您的代码的时间可能更加昂贵,这就是简单/清晰度更为重要的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM