Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider adding support to use lambda functions as attributes #48

Closed
langzhaozhi opened this issue Dec 23, 2015 · 4 comments
Closed

Consider adding support to use lambda functions as attributes #48

langzhaozhi opened this issue Dec 23, 2015 · 4 comments
Assignees

Comments

@langzhaozhi
Copy link

(1)对象上的属性支持lambda,而当前使用匿名内部类的方式非常不爽,尤其Java8了,看到匿名内部类就有种本能的退缩感觉(The property on the object supports lambda, and the current use of anonymous inner classes is very uncomfortable, especially Java8 when seeiing the anonymous inner class has a kind of instinctive retreat)

eg:
public static final Attribute<Car, Integer> CAR_ID = new SimpleAttribute<Car, Integer>( "carId") {
@OverRide
public Integer getValue(Car car, QueryOptions queryOptions ) {
return car.carId;
}
};

该被类似如下简洁lambda代替:should be replaced by some followings:

public static final Attribute<Car, Integer> CAR_ID = new SimpleAttribute<Car,Integer>("carId", (car,queryOptions) => car.carId );

(2) 应该支持基本类型的属性,类似 Java8 中的 IntFunction,DoubleFunction 之类,原因是查询往往在大数据量中的应用,应该想尽一切办法消除自动装箱拆箱的性能损耗以达到最高的运行效率[Should support the primitives types of attributes, like DoubleFunction IntFunction similar in java8. The reason is that queries are often in a large amount of data application, CQEngine should try every possible way to eliminate the performance loss of the automatic boxing and unboxing in order to achieve the highest efficiency]

eg:

public static final Attribute<Car, Integer> CAR_ID = new SimpleAttribute<Car, Integer>( "carId") {
@OverRide
public Integer getValue(Car car, QueryOptions queryOptions ) {
return car.carId;
}
};

可使用如下:(Maybe use followings:)

public static final IntAttribute CAR_ID = new IntAttribute("carId"){
@OverRide
public int getValue(Car car, QueryOptions queryOptions ) {
//no boxing Integer here!
return car.carId;
}
};

and lambda support above:

public static final IntAttribute CAR_ID = new IntAttribute("carId", (car,queryOptions) => car.carId);

@npgall
Copy link
Owner

npgall commented Dec 23, 2015

Hi langzhaozhi, I'm accepting this suggestion, thanks.

I plan that the next major version of CQEngine will integrate more closely with Java 8 features such as lambdas and method handles. Especially method handles, would simplify attributes a lot.

The current version is compatible with Java 6, so these changes are not yet possible. Hopefully in the new year I can do it though. Thanks!

@npgall npgall self-assigned this Dec 23, 2015
@npgall npgall changed the title 两点建议[Two suggestions] Consider adding support to use lambda functions as attributes Jan 27, 2016
@npgall
Copy link
Owner

npgall commented Sep 20, 2016

This is now done. When run on Java 8, CQEngine 2.8.0 now allows attributes to be created from lambda expressions. It was possible to implement this in a way that retained compatibility with Java 6 & 7, so CQEngine still works with those earlier versions of Java too.

@npgall npgall closed this as completed Sep 20, 2016
@sp-1234
Copy link

sp-1234 commented Jul 14, 2017

How about primitives support to avoid boxing? It was also suggested above but I'm not sure if it's done.

Should support the primitives types of attributes, like DoubleFunction IntFunction similar in java8. The reason is that queries are often in a large amount of data application, CQEngine should try every possible way to eliminate the performance loss of the automatic boxing and unboxing in order to achieve the highest efficiency

@npgall
Copy link
Owner

npgall commented Jul 17, 2017

I don't think this would be a high priority or much of a problem.

Boxing overhead is usually a much bigger problem than unboxing overhead, and boxing overhead should already be mitigated to a large extent.

Currently all primitives are stored in boxed form when using on-heap persistence and indexes. So it means there should not be any boxing overhead during query processing. There will be unboxing overhead, but this does not produce any garbage.

Off-heap persistence and indexes store data in primitive format. This means when suitable indexes are available to support the query during query processing, the values from queries will be unboxed and compared with primitive values inside indexes. So this entails unboxing (not boxing) as well, which means there should not be much boxing/GC overhead either.

However if the collection is using off-heap persistence or indexes, but certain queries can't be answered from a single index, then filtering will be performed. Filtering can involve deserializing objects speculatively to check if they match the query, which can be quite expensive. However in applications where this is a problem, an alternative "merge" strategy can be configured (the index merge strategy) which performs joins between indexes instead of deserializing objects speculatively, which can reduce that overhead.

So I think we need to see actual evidence of boxing or unboxing being a performance bottleneck before making API changes to support primitives. If anybody wants to do some proof of concepts or testing in this area I'd be open to collaborating though!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants