我怎么能快速做到这一点?
当然,我可以这样做:
static bool ByteArrayCompare(byte[] a1, byte[] a2)
{
if (a1.Length != a2.Length)
return false;
for (int i=0; i<a1.Length; i++)
if (a1[i]!=a2[i])
return false;
return true;
}
Run Code Online (Sandbox Code Playgroud)
但我正在寻找BCL功能或一些经过高度优化的可靠方法来实现这一目标.
java.util.Arrays.equals((sbyte[])(Array)a1, (sbyte[])(Array)a2);
Run Code Online (Sandbox Code Playgroud)
很好地工作,但它看起来不适用于x64.
请注意我的超快速的答案在这里.
这有点令人费解.以下代码是一个小测试应用程序的一部分,用于验证代码更改未引入回归.为了使它快速,我们使用memcmp这似乎是比较两个相同大小的图像(不出所料)的最快方式.
但是,我们有一些测试图像显示出一个相当令人惊讶的问题:memcmp在位图数据上告诉我们它们不相等,但是,逐像素比较根本没有发现任何差异.我的印象是,当你使用LockBitsa时,Bitmap你会获得图像的实际原始字节.对于24 bpp位图,有点难以想象像素相同但基础像素数据不相同的情况.
一些令人惊讶的事情:
00一个图像和另一个图像FF中的单个字节.PixelFormat对LockBits向Format32bppRgb或者Format32bppArgb,比较成功.BitmapData第一次LockBits调用返回的返回值作为第四个参数传递给第二个参数,则比较成功.我有点难过,因为坦白说我无法想象为什么会这样.
(简化)代码如下.只需编译csc /unsafe并传递一个24bpp的PNG图像作为第一个参数.
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
class Program
{
public static void Main(string[] args)
{
Bitmap title = new Bitmap(args[0]);
Console.WriteLine(CompareImageResult(title, new Bitmap(title)));
}
private static string CompareImageResult(Bitmap bmp, Bitmap expected) …Run Code Online (Sandbox Code Playgroud) 我正在研究一个IEqualityComparer应该比较快速地比较原始类型的数组.我的计划是获取指向数组和memcmp它们的指针.像这样:
public unsafe override bool Equals(T[] x, T[] y)
{
if (ReferenceEquals(x, y)) return true;
if (x == null || y == null) return false;
if (x.Length != y.Length) return false;
var xArray = (Array)x;
var yArray = (Array)y;
fixed (void* xPtr = xArray) //compiler error 1
fixed (T* yPtr = y) //compiler error 2
{
return memcmp(xPtr, yPtr, x.Length * this.elementSize);
}
}
Run Code Online (Sandbox Code Playgroud)
固定语句不允许我固定Array或T[].
有错误消息是:
1. Cannot implicitly convert type 'System.Array' …Run Code Online (Sandbox Code Playgroud) 比较2个BitmapImage对象的最快方法是什么.一个是在Image Source属性中,另一个是我在代码中创建的.
我可以使用新的位图图像设置图像源,但它会导致闪烁,因为它会一遍又一遍地设置相同的图像.
我想只设置图像,如果它的像素与Image.Source中的像素不同.
编辑:
AlbumArt是视图中的图像(跟随MVVM).
一些代码(在视图代码后面运行):
Task.Factory.StartNew(() =>
{
while (((App)Application.Current).Running)
{
Thread.Sleep(1000);
Application.Current.Dispatcher.Invoke(new Action(() =>
{
if ((this.DataContext as AudioViewModel).CurrentDevice != null)
{
if ((((this.DataContext as AudioViewModel).CurrentDevice) as AUDIO).SupportsAlbumArt)
{
BitmapImage image = new BitmapImage();
image.BeginInit();
image.UriSource = new Uri((((this.DataContext as AudioViewModel).CurrentDevice) as AUDIO).AlbumArt);
image.CacheOption = BitmapCacheOption.None;
image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
image.EndInit();
AlbumArt.Source = image;
...
Run Code Online (Sandbox Code Playgroud)