我正在尝试优化我的代码。一个电话很快,但因为我经常遇到一些问题。
我的输入数据如下所示:
public function product()
{
return $this->belongsTo('App\Product');
}
现在我只想申请一个简单的功能。以下是我想要优化的部分:
public void setClickListener(View.OnClickListener callback) {
mClickListener = callback;
}
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType)
{
if (viewType == AD_TYPE) {
View inflatedView;
if (AD_FORM == 3) {
inflatedView = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.ad_unit, viewGroup, false);
}
else {
inflatedView = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.ad_unit2, viewGroup, false);
}
return new AdHolder(inflatedView);
}
else {
View inflatedView = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.feed_item, viewGroup, false);
PersonViewHolder personViewHolder = new PersonViewHolder(inflatedView);
personViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mClickListener.onClick(view);
}
});
return personViewHolder;
}
}
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position)
{
if (holder.getItemViewType() == AD_TYPE) {
if (mAd != null) {
((AdHolder)holder).bindView(mAd);
}
else if (mAds != null && mAds.isLoaded()) {
mAd = mAds.nextNativeAd();
((AdHolder)holder).bindView(mAd);
}
else {
((AdHolder)holder).bindView(null);
}
}
else {
i = position;
if (i != 0) {
i--;
}
String cover = "https://www.stanzascoop.com/covers/"+ persons.get(i).photoId;
String avi = "https://www.stanzascoop.com/avis/"+ persons.get(i).photo;
final String views = NumberFormat.getInstance().format(persons.get(i).viewcount) + " scoops";
((PersonViewHolder)holder).uploadUser.setText(persons.get(i).username);
((PersonViewHolder)holder).uploadDate.setText(persons.get(i).uploaddate);
((PersonViewHolder)holder).personName.setText(persons.get(i).name);
((PersonViewHolder)holder).personAge.setText("by "+ persons.get(i).age);
((PersonViewHolder)holder).viewCount.setText(views);
context = mContext;
Picasso.with(context).load(cover).transform(new RoundedTransformation(0, 0)).fit().into(((PersonViewHolder)holder).personPhoto);
Picasso.with(context).load(avi).transform(new RoundedTransformation(100, 0)).fit().into(((PersonViewHolder)holder).authorPhoto);
((PersonViewHolder)holder).setClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int s = getItemCount();
int pos = ((PersonViewHolder)holder).getAdapterPosition();
Log.e(TAG, "POS: "+ ((PersonViewHolder)holder).getItemId());
openLyric(persons.get(i).name, persons.get(i).content, persons.get(i).age, persons.get(i).photoId, views, persons.get(i).lurl);
}
});
}
}
现在我得到1000个循环,最好的3个:每个循环1.36毫秒。我想应该可以更快地做到这一点。不确定我是否应该进行矢量化,只能使用numpy或者使用cython。最好的方法是什么想法?我和班次操作员有点挣扎。
答案 0 :(得分:1)
您可以将比较结果直接从bool
转换为int
:
(df >= df.shift(1)).astype(int)
答案 1 :(得分:0)
这是我目前最好的解决方案:
values = df.values[1:] >= df.values[:-1]
data = np.array(values, dtype=int)
s = pd.DataFrame(data, df.index[1:])
我得到10000个循环,最好是每个循环3:125μs。 x10改进。但我认为它可以做得更快。
PS:这个解决方案并不完全正确,因为缺少第一个零/ nan。 PPS:可以通过pd.DataFrame(np.append([[0]],data),df.index)来修正
答案 2 :(得分:0)
@Paul H的答案很好,性能也很好,我一般都会推荐。
也就是说,如果你想挤出最后一点性能,这是numba
的一个不错的选择,你可以用它来计算一次通过数据的答案。
from numba import njit
@njit
def do_calc(arr):
N = arr.shape[0]
ans = np.empty(N, dtype=np.int_)
ans[0] = 0
for i in range(1, N):
ans[i] = 1 if arr[i] > arr[i-1] else 0
return ans
a = (df >= df.shift(1)).astype(int)
b = pd.DataFrame(pd.Series(do_calc(df[0].values), df[0].index))
from pandas.testing import assert_frame_equal
assert_frame_equal(a, b)
这是时间
In [45]: %timeit b = pd.DataFrame(pd.Series(do_calc(df[0].values), df[0].index))
135 µs ± 1.83 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [46]: %timeit a = (df >= df.shift(1)).astype(int)
762 µs ± 22.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)