小编Wil*_*ood的帖子

为什么我的应用程序花费24%的时间进行空检查?

我有一个性能关键的二元决策树,我想把这个问题集中在一行代码上.下面是二叉树迭代器的代码,其中包含针对它运行性能分析的结果.

        public ScTreeNode GetNodeForState(int rootIndex, float[] inputs)
        {
0.2%        ScTreeNode node = RootNodes[rootIndex].TreeNode;

24.6%       while (node.BranchData != null)
            {
0.2%            BranchNodeData b = node.BranchData;
0.5%            node = b.Child2;
12.8%           if (inputs[b.SplitInputIndex] <= b.SplitValue)
0.8%                node = b.Child1;
            }

0.4%        return node;
        }
Run Code Online (Sandbox Code Playgroud)

BranchData是一个字段,而不是属性.我这样做是为了防止它被内联的风险.

BranchNodeData类如下:

public sealed class BranchNodeData
{
    /// <summary>
    /// The index of the data item in the input array on which we need to split
    /// </summary>
    internal int SplitInputIndex = 0;

    /// <summary>
    /// The …
Run Code Online (Sandbox Code Playgroud)

c# optimization performance il micro-optimization

103
推荐指数
2
解决办法
4363
查看次数

结构内存破解重叠对象引用 - 是否可能?

我猜这个问题的答案是"这是不可能的,切换到C++".但我还以为我会把它扔出去.

我正在处理一个巨大的二叉树.我有一个结构数组来表示我在迭代树时用来帮助处理内存的分支节点.

为了节省一点内存,从而改善缓存局部性,我正在考虑重叠叶节点的对象引用.该对象引用将指向所有叶数据.基本上,这样的事情:

[StructLayout(LayoutKind.Explicit)]
struct BranchData
{
    [FieldOffset(0)] // 1 byte
    internal byte SplitIndex;
    [FieldOffset(1)] // 4 bytes
    internal float SplitValue;
    [FieldOffset(5)] // 4 bytes
    internal int LowIndex;
    [FieldOffset(9)] // 4 bytes
    internal int HighIndex;
    [FieldOffset(0)] // 8 bytes (We're working with x64 here)
    internal LeafData Node;
}
Run Code Online (Sandbox Code Playgroud)

上面给出了以下运行时错误

无法从程序集"WindowsFormsApplication1,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null"加载类型"BranchData",因为它包含偏移0处的对象字段,该字段未正确对齐或由非对象字段重叠.

我可以使用一个单独的数组来存储叶子数据,并使用索引指向该数组,但后来我有2个内存查找(对于什么当然是远处的内存区域).一个用于叶子数组中的位置以获取引用,另一个用于获取叶子数据.如果我可以实现这种重叠,我摆脱了其中一个查找.

我能够固定对象并使用不安全的代码来解决这个问题.速度是这里的关键因素.

.net c# performance memory-management

14
推荐指数
1
解决办法
1921
查看次数

.NET字典,速度惊人,但它是如何工作的?

好吧,我会承认我没有挖出反射器来看看这里发生了什么,但我希望有人可以告诉我.

Microsoft如何快速地添加和获取,我可以通过在数组中粘贴项目来快速添加,并且我可以通过对数组进行排序和使用二进制搜索来快速获取.但是,如果我每次添加一个项目以快速获取数据时都会进行快速排序,那么添加会大幅减慢速度,如果每次我尝试获取某些内容时都必须对数据进行排序,那么添加项目会大大减慢.

有谁知道字典的内部工作原理?它比数组更需要内存,所以除了聪明的算法之外,显然还有一些东西在幕后进行.

我正在努力理解魔法并从中学习!

.net memory performance dictionary

13
推荐指数
3
解决办法
5142
查看次数

如何处理DeadObjectException?

在请求购买应用程序的价格时,我从某些设备收到DeadObjectException的异常报告.当我在我的结算服务连接上调用getSkuDetails时会发生异常.

我没有发现这方面的文件特别清楚.

您呼叫的对象已经死亡,因为其托管过程不再存在.

  1. 如果我认为Android出于某种原因已经杀死了结算服务,我是否正确理解了这一点?
  2. 为什么?
  3. 有没有办法阻止这种情况发生?
  4. 我应该阻止这种情况发生吗?
  5. 我应该如何处理异常?
  6. 有没有办法可以重现这个场景进行测试?

我有两种方法

void bindToBillingService() {
    AndroidLauncher.getActivity().bindService(new Intent("com.android.vending.billing.InAppBillingService.BIND"),
            mServiceConn, Context.BIND_AUTO_CREATE);
}

public void unbindBillingService() {
    if (getBillingServiceConnection() != null) {
        AndroidLauncher.getActivity().unbindService(mServiceConn);
    }
}
Run Code Online (Sandbox Code Playgroud)

我应该这样做吗?

    try {
        // Do something billing related
    } catch (DeadObjectException e) {
        unbindBillingService();
        bindToBillingService();
        // Wait for a connection and then try again
    }
Run Code Online (Sandbox Code Playgroud)

android in-app-purchase google-play-services

11
推荐指数
0
解决办法
1642
查看次数

我可以使用比树更快的数据结构吗?

我有一个二元决策树.它将输入作为一个浮点数组,每个分支节点在输入索引和值上分割,最终将我带到一个叶子.

我在这棵树上执行了大量的查找(根据性能分析,大约17%的执行时间(编辑:优化了其他区域,现在几乎达到40%)),我想知道我是否可以/应该使用不同的数据结构,以提高查找速度.

某些哈希表不能使用,因为输入不直接映射到叶节点,但我想知道是否有人建议我可以用来代替树的方法和数据结构(或者也是如此) as?)提高查找速度.

记忆是一个值得关注的问题,但不是速度问题.

代码目前用C#编写,但显然可以应用任何方法.

编辑:发布的代码太多了,但我会提供有关树的更多细节.

树是使用信息增益计算生成的,它并不总是50/50分割,分割值可以是任何浮点值.单个输入也可以多次拆分,从而提高该输入的分辨率.

我在这里发布了一个关于迭代器性能的问题:

在C#中迭代树的微优化

但我想我可能需要查看数据结构本身以进一步提高性能.

我的目标是尽可能多的表现.我正在研究一种新的机器学习方法,树使用反馈循环自我增长.对于我正在研究的过程,我估计它将运行几个月,所以在这里节省了几个百分点.最终目标是在不使用太多内存的情况下提高速度.

performance data-structures

7
推荐指数
1
解决办法
330
查看次数

使用预乘alpha时,AlphaGL渐变在WebGL中不平滑

我有一个带有平滑渐变的卡通云的LibGDX游戏.游戏中还有其他具有类似问题的渐变示例,但云是最明显的例子.它们在Android,iOS和游戏的桌面版本上都很好看,但在WebGL版本中,渐变并不是那么平滑.它似乎只是alpha梯度有问题.其他渐变看起来不错.

我在Chrome和IE中尝试了3种不同的设备,所有3种设备都产生相同的结果.您可以在此处找到HTML5版本的测试.

https://wordbuzzhtml5.appspot.com/canvas/

我在github上添加了一个示例IntelliJ项目

https://github.com/WillCalderwood/CloudTest

如果你有intelliJ,克隆该项目,打开build.gradle文件,按Alt-F12,键入gradlew html:superdev然后浏览到http:// localhost:8080/html /

关键代码在render() 这里

这里的底部图像是桌面版本,顶部是WebGL版本,两者都在相同的硬件上运行.

在此输入图像描述

绘图没有什么巧妙的.这只是一个电话

    spriteBatch.draw(texture, getLeft(), getBottom(), getWidth(), getHeight());
Run Code Online (Sandbox Code Playgroud)

我正在使用默认着色器,纹理用预乘alpha填充,混合函数设置为

    spriteBatch.setBlendFunction(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA);
Run Code Online (Sandbox Code Playgroud)

这是实际的图像,虽然alpha不是像我的包装工那样预乘的.

在此输入图像描述

有谁知道这个的可能原因以及我如何解决它?

更新

仅在使用混合模式时才会出现这种情况 GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA

另一个更新

我已经尝试改变整个游戏以使用非预乘的alpha纹理.我使用Texture Packer可以帮助修复非预乘alpha经常出现的晕圈问题.所有这些在Android和桌面版本中都能正常工作.在WebGL版本中,虽然我得到了平滑的渐变,但我仍然得到一个小的光晕效果,所以我不能用它作为解决方案.

另一个更新

这是一张新图片.桌面版本位于顶部,网页版本位于底部.GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA左侧和GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA右侧的混合模式

在此输入图像描述

这是上面左下角图像的缩放版本,增加对比度以显示问题.

在此输入图像描述

我还做了大量的片段着色器,试图找出正在发生的事情.如果我订

gl_FragColor = vec4(c.a, c.a, c.a, 1.0);
Run Code Online (Sandbox Code Playgroud)

然后渐变是平滑的,但如果我设置

gl_FragColor = vec4(c.r, c.r, c.r, 1.0);
Run Code Online (Sandbox Code Playgroud)

然后我得到了条带.这指向了一个精确的问题我相信,因为色彩通道已被预乘法过程挤入光谱的较暗端.

html5 blending opengl-es webgl libgdx

7
推荐指数
2
解决办法
1041
查看次数

Firebase邀请错误 - 链接无法正常工作

我正在努力让Firebase邀请工作.我按照这里的说明进行操作.

触发邀请过程的代码如下

        AppInviteInvitation.IntentBuilder intentBuilder = new AppInviteInvitation.IntentBuilder(LanguageManager.getString("title-Invitation"))
                .setMessage(LanguageManager.formatString("message-INVITATION_{game-name}", ScribbleGame.getGame().getDisplayName()))
                .setEmailSubject(LanguageManager.formatString("title-TRY_{game_name}", ScribbleGame.getGame().getDisplayName()))
                .setEmailHtmlContent(emailHtml);

        application.startActivityForResult(intentBuilder.build(), ActivityResultConstants.REQUEST_INVITE);
Run Code Online (Sandbox Code Playgroud)

电子邮件包含使用%%APPINVITE_LINK_PLACEHOLDER%%标记插入的链接.邀请按预期发送.

我已经尝试了有无深层链接.如果没有深层链接,我会得到一个这样的URL,它不起作用并返回404错误.

https://plus.google.com/appinvite/131189621476-3ec41294-23ea-47e7-81d7-9a5fd004de6e

使用深层链接,我得到一个这样的URL,它不起作用并返回500错误.

https://sfqj5.app.goo.gl/i/131189621476-b6d8a1cf-81b4-4318-90d0-c32ee1a945e1

我已经做了很多挖掘,但未能确定链接无法正常工作的原因.

android firebase firebase-invites

7
推荐指数
1
解决办法
678
查看次数

"可能无法加载受污染的画布"WebGL纹理的跨域问题

我在过去48小时内学到了很多关于跨域策略的知识,但显然还不够.

这个问题之后.我的HTML5游戏支持Facebook登录.我正在尝试下载人们朋友的个人资料照片.在我的游戏的HTML5版本中,我在Chrome中遇到以下错误.

detailMessage:"com.google.gwt.core.client.JavaScriptException :( SecurityError)↵stack:错误:无法在'WebGLRenderingContext'上执行'texImage2D':可能无法加载受污染的画布.

据我所知,出现此错误是因为我正在尝试从其他域加载图像,但这可以使用Access-Control-Allow-Origin标头解决,详见问题.

我试图从中下载的URL是

https://graph.facebook.com/1387819034852828/picture?width=150&height=150

查看Chrome中的网络标签,我可以看到它具有所需的access-control-allow-origin标头,并通过302重定向到新URL进行响应.该URL有所不同,我想这取决于负载平衡,但这是一个示例URL.

https://fbcdn-profile-a.akamaihd.net/hprofile-ak-xap1/v/t1.0-1/c0.0.160.160/p160x160/11046398_1413754142259317_606640341449680402_n.jpg?oh=6738b578bc134ff207679c832ecd5fe5&oe=562F72A4& GDA = 1445979187_2b0bf0ad3272047d64c7bfc2dbc09a29

此URL还具有access-control-allow-origin标头.所以我不明白为什么会失败.

作为Facebook,以及成千上万的应用程序,游戏和网站显示用户个人资料图片的事实,我认为这是可能的.我知道我可以通过我自己的服务器弹跳,但我不知道为什么我应该这样做.

回答

我最终使用以下代码在libgdx中进行跨域映像加载(这非常hacky,我确信可以改进).我还没有设法使用AssetDownloader.我希望最终可以解决这个问题.

public void downloadPixmap(final String url, final DownloadPixmapResponse response) {
    final RootPanel root = RootPanel.get("embed-html");
    final Image img = new Image(url);
    img.getElement().setAttribute("crossOrigin", "anonymous");
    img.addLoadHandler(new LoadHandler() {

        @Override
        public void onLoad(LoadEvent event) {
            HtmlLauncher.application.getPreloader().images.put(url, ImageElement.as(img.getElement()));
            response.downloadComplete(new Pixmap(Gdx.files.internal(url)));
            root.remove(img);
        }
    });
    root.add(img);
}

interface DownloadPixmapResponse {
    void downloadComplete(Pixmap pixmap);

    void downloadFailed(Throwable e);
}
Run Code Online (Sandbox Code Playgroud)

gwt google-chrome webgl libgdx html5-canvas

6
推荐指数
1
解决办法
1万
查看次数

Android 应用链接在已发布的版本中无法正常工作,但在本地安装中可以正常工作

我有一个使用应用链接的游戏。从我的计算机运行调试和发布版本时,应用程序链接工作正常,但不适用于从 Google Play 下载的版本。使用 Google Play 版本时,我会收到一个对话框,询问哪个应用程序应该打开链接。

我使用“Google Play 应用签名”并了解发布的 APK 由 Google 签名并具有不同的签名。我已将 Google Play 上列出的应用签名证书中的 SHA-256 证书指纹添加到我的assetlinks.json 中,因此它包含来自本地和 Google Play 版本的指纹。

我还从 Google Play 下载了一个派生的 APK,并确保指纹与 assetlinks.json 文件中的指纹匹配。

这是一个示例 URL,在 Android 中单击该 URL 时应打开该应用程序,它适用于本地构建,但不适用于 Google Play 版本。相反,我收到一个对话框,询问哪个应用程序应该打开链接。

https://letsdraw.fun/ec?parent=Z0ibN7m-H8jO1jCiMRQtY23VTpKjnIch

我正在从实时发布版本的 logcat 中写出 SHA256 指纹,以仔细检查它是否正确,并且看起来一切正常。

原始签名的 APK 和 Google Play 签名的 APK 可以从这里下载。这两个 APK 都是从 Google Play 下载的,一个是“原始的”,一个是“衍生的”,因此除了签名之外,它们应该是相同的。有趣的是,它们的尺寸略有不同。11,590,297 字节 vs 11,601,619 字节。

查看adb shell dumpsys package domain-preferred-apps原始签名 apk的输出是

  Package: com.scribble.exquisitecorpse
  Domains: letsdraw.fun …
Run Code Online (Sandbox Code Playgroud)

android applinks android-app-links

6
推荐指数
1
解决办法
991
查看次数

我疯了还是Math.Pow坏了?

我从这里使用了基本转换器并将其更改为使用ulong值,但是当转换大数字时,特别是高于16677181699666568的数字时,它返回的值不正确.我开始研究这个并发现Math.Pow(3,34)返回值16677181699666568,而实际上3 ^ 34是16677181699666569.这因此为我投入了一个扳手.我认为这只是Pow方法中双精度的问题吗?我最简单的解决方法是创建我自己的Pow,它需要ulong值吗?

如果是这样,做Pow的最快方法是什么?我假设每次都有一个比for循环更快的东西.

c# precision double pow

3
推荐指数
3
解决办法
1898
查看次数

Admob直到第二次请求才会显示广告

关于这个以及一些不同的答案有几个问题 - 这些问题似乎都不适用于我.

我有一个libdgx应用程序,这让我觉得有点复杂,但我没有看到它应该导致问题.我的onCreate的代码如下.

我已经分配了一个AdListener,在加载add时会调用它.这个代码被击中但没有显示任何内容.如果我将广告设置为刷新,那么它将在第一次刷新后显示.如果我在短暂等待后第二次调用loadAd,则会显示横幅.如果我在两行连续的代码上调用loadAd,广告将不会显示.关于这里可能会发生什么的任何指示都将不胜感激.

编辑:我也注意到我可以点击广告,即使我看不到广告.当我返回到点击广告的游戏时,广告正确显示.

edit2:我将广告更改为SMART_BANNER而不是BANNER,这似乎按预期工作.我仍然不知道为什么BANNER不工作.

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Create the layout
    FrameLayout layout = new FrameLayout(this);


    // Do the stuff that initialize() would do for you
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(
            WindowManager.LayoutParams.FLAG_FULLSCREEN
                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
            WindowManager.LayoutParams.FLAG_FULLSCREEN
                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
    );
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);

    AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
    config.useAccelerometer = false;
    config.useCompass = false;
    config.useWakelock = false;
    config.useImmersiveMode = true;
    config.hideStatusBar = true;

    // Create the libgdx View
    View gameView = initializeForView(new WordStormGame(this), config);

    // Add the libgdx view
    layout.addView(gameView);

    adView …
Run Code Online (Sandbox Code Playgroud)

android admob libgdx

3
推荐指数
1
解决办法
921
查看次数

没有更新电池优化时不渲染 - libgdx

我正在寻找一种在我正在开发的游戏中最大限度地减少电池使用量,并且电池使用量很难准确测量,所以我希望知道的人能够回答这个问题.

是否值得我实现一个系统,当屏幕上显示的内容没有更新时我不会渲染?就像是

updated = false;

for each component
  updated |= component.update();

if (updated)
  render();
Run Code Online (Sandbox Code Playgroud)

如果它是值得的,那么这种事情在开始时更容易添加,而不是在需要时尝试添加.

如果我通过CPU渲染,那么我肯定会说它值得做,但通过GPU我不太确定.与屏幕上的东西相比,是否可以节省大量的电池?

编辑: 有点澄清.我正在创建一个文字游戏,所以很多时候用户都会盯着一个不动的屏幕寻找单词.根据正在播放游戏的模式,屏幕上可能会发生一些不是由用户输入触发的事情.例如,屏幕上每5秒出现一个新对象.渲染300帧,每5秒钟没有任何事情发生似乎是一种真正的浪费,这是我想要避免的.

android battery opengl-es libgdx 2d-games

1
推荐指数
1
解决办法
744
查看次数

TEdit没有在Delphi 5中使用Invalidate正确重绘

在某些系统上使用Cirtix时,Delphi 5中的TScrollBox存在问题,当用户通过单击滚动条末端顶部或底部的按钮滚动整个应用程序时会冻结.我们最初在QucikReports预览中遇到了问题,并通过在TScrollBox中实现我们自己的滚动条来解决它.

我们现在有一个使用TScrollBox的定制工作,客户端报告类似的问题,所以我以同样的方式解决它.我隐藏了TScrollBox滚动条并添加了我自己的滚动条.单击这些时,我会调用以下内容.

请注意,此测试代码目前尚未在Citrix中运行,我已经在XP和Window 7上进行了测试.

我正在关闭重绘控件,移动所有子控件,然后重新开启绘图并调用Invalidate.我希望invalidate完全重绘控件但是没有发生.

procedure TScrollBoxScrollReplacement.ScrollControls(x: Integer; y: Integer);
var
  I: Integer;
begin
  if (x = 0) and (y = 0) then
    Exit;

  // Stop the control from repaining while we're updating it
  try
    SendMessage(FScrollBox.Handle, WM_SETREDRAW, 0, 0);

    for I := 0 to FScrollBox.ControlCount - 1 do
    begin
      if (FScrollBox.Controls[I] = FVScrollBar) or (FScrollBox.Controls[I] = FHScrollBar) then
        Continue;

      FScrollBox.Controls[I].Left := FScrollBox.Controls[I].Left + x;
      FScrollBox.Controls[I].Top := FScrollBox.Controls[I].Top + y;
    end;

  finally
    // Turn on painting again
    SendMessage(FScrollBox.Handle, WM_SETREDRAW, 1, …
Run Code Online (Sandbox Code Playgroud)

delphi delphi-5

0
推荐指数
2
解决办法
611
查看次数