samsung precio pen note lapiz con delphi

delphi - pen - samsung galaxy note 8 precio



Puntero(s) ^ contra s (7)

Definitivamente la notación matricial. Parte del estilo de Delphi es hacer que su código sea fácil de leer, y es más fácil saber qué está pasando cuando explica exactamente lo que está haciendo. Lanzar una cadena a un puntero y luego anular la referencia parece confuso; porque haces eso No tiene sentido a menos que el lector sepa mucho sobre los internos de las cuerdas.

En una función que lee datos (datos que significan exclusivamente cadenas) del disco, ¿cuál debería preferir? ¿Cual es mejor?

A) DiskStream.Read(Pointer(s)^, Count) or B) DiskStream.Read(s[1], Count)

Nota:
Sé que ambos están teniendo el mismo resultado.
Sé que tengo que SetLength of S antes de llamar a Read.

ACTUALIZAR

S es AnsiString.

Aquí está la función completa:

{Lee un montón de caracteres del archivo. ¿Por qué ''ReadChars'' y no ''ReadString''? Esta función lee cadenas de C ++ (la longitud de la cadena no se escribió en el disco también). Entonces, tengo que dar el número de caracteres para leer como parámetro. }

function TMyStream.ReadChars(out s: AnsiString; CONST Count: Longint): Boolean; begin SetLength(s, Count); Result:= Read(s[1], Count)= Count; end;

Prueba de velocidad

En mi prueba de velocidad, el primer acercamiento fue un poquito más rápido que el segundo. Utilicé un archivo de 400MB desde el cual leí cadenas unas 200000 veces. El proceso se estableció en Alta prioridad.

El mejor tiempo de lectura fue:
1.35 para la variante B y 1.37 para la variante A.
Promedio:
En promedio, B estaba anotando 20ms mejor que A.

La prueba se repitió 15 veces para cada variante.

La diferencia es muy pequeña. Podría caer en el rango de error de medición. Probablemente será significativo si leo cadenas con mayor frecuencia y de un archivo más grande. Pero por el momento digamos que ambas líneas de código están realizando lo mismo.

RESPONDER
Variante A: podría ser un poquito más rápido. Variante B: es (obviamente) mucho más fácil de leer y es más Delphi-ish. Mi preferido

Nota:
He visto Embarcadero usando la variante A en el ejemplo TStreamReadBuffer, pero con un TBytes en lugar de String.


El segundo (DiskStream.Read (s [1], Count)). Cuando te encuentras con un parámetro var sin tipo, se lee como "toma la dirección de lo que se pasa como parámetro". Entonces, en este caso, está pasando la dirección del primer carácter de la cadena s, que es lo que pretendía hacer.


La segunda opción es definitivamente más "estilo Delphi" (si observa las versiones Delphi de los encabezados de API de Windows, verá que la mayoría de los parámetros de puntero se han convertido a parámetros var ).

Además de eso, la segunda opción no necesita un lanzamiento y es IMHO mucho más legible.


Si existe alguna posibilidad de que se llame a su función con un conteo de 0, entonces A) funcionará con Pointer(s)^ simplemente evaluando a nil mientras que B) se bloqueará con una excepción de verificación de rango.

Si desea usar B) y aún manejar los conteos de 0 con gracia, debe usar:

function TMyStream.ReadChars(out s: AnsiString; const Count: Integer): Boolean; begin SetLength(s, Count); Result := (Count = 0) or (Read(s[1], Count) = Count); end;


Si le interesa la optimización, debería preferir la primera variante. Basta con mirar el código generado por el compilador:

Unit7.pas.98: Stream.Read(Pointer(S)^, 10); 00470EA9 8B55FC mov edx,[ebp-$04] 00470EAC B90A000000 mov ecx,$0000000a 00470EB1 8BC6 mov eax,esi 00470EB3 8B18 mov ebx,[eax] 00470EB5 FF530C call dword ptr [ebx+$0c] Unit7.pas.99: Stream.Read(s[1], 10); 00470EB8 8B5DFC mov ebx,[ebp-$04] 00470EBB 85DB test ebx,ebx 00470EBD 7418 jz $00470ed7 00470EBF 8BC3 mov eax,ebx 00470EC1 83E80A sub eax,$0a 00470EC4 66833802 cmp word ptr [eax],$02 00470EC8 740D jz $00470ed7 00470ECA 8D45FC lea eax,[ebp-$04] 00470ECD 8B55FC mov edx,[ebp-$04] 00470ED0 E8CB3FF9FF call @InternalUStrFromLStr 00470ED5 8BD8 mov ebx,eax 00470ED7 8D45FC lea eax,[ebp-$04] 00470EDA E89950F9FF call @UniqueStringU 00470EDF 8BD0 mov edx,eax 00470EE1 B90A000000 mov ecx,$0000000a 00470EE6 8BC6 mov eax,esi 00470EE8 8B18 mov ebx,[eax] 00470EEA FF530C call dword ptr [ebx+$0c]

ACTUALIZAR

El código anterior es generado por el compilador Delphi 2009. Puede mejorar el código usando la directiva {$ STRINGCHECKS OFF}, pero todavía tiene UniqueStringU sobrecarga de llamadas a la función UniqueStringU :

Unit7.pas.100: Stream.Read(s[1], 10); 00470EB8 8D45FC lea eax,[ebp-$04] 00470EBB E8B850F9FF call @UniqueStringU 00470EC0 8BD0 mov edx,eax 00470EC2 B90A000000 mov ecx,$0000000a 00470EC7 8BC3 mov eax,ebx 00470EC9 8B18 mov ebx,[eax] 00470ECB FF530C call dword ptr [ebx+$0c]


Siempre uso el segundo que mantiene el tipo de seguridad. Realmente no compro el argumento de rendimiento, ya que está a punto de golpear el disco en el peor de los casos, o el caché de archivos, o la memoria principal, todo lo cual hará que un puñado de operaciones de la CPU parezcan algo triviales. La corrección debe tener mayor prioridad que el rendimiento.

Sin embargo, añadiría que esto no es algo que deba molestarle demasiado, ya que debe escribir este fragmento de código en particular una sola vez. Ponlo en una clase de ayuda y envuélvelo bien. Siéntase libre de preocuparse por la optimización, vuelva a escribirla como ensamblador, lo que sea más atractivo para usted. Pero no te repito.


Ten en cuenta que cuando corres

1. DiskStream.Read(Pointer(s)^, Count) 2. DiskStream.Read(s[1], Count)

La versión 1. será más rápida.

Pero debe asegurarse de que la variable s sea explícitamente local , o se haya llamado UniqueString(s) antes del bucle.

Ya que el pointer(s)^ no llamará a UniqueString?() Llamada RTL oculta de bajo nivel, será más rápido que s[1] , pero puede anular algunos datos existentes si la variable de cadena s se comparte entre el contexto actual y otro contexto (por ejemplo, si el último contenido de s se recuperó de una función de un valor de propiedad, o s se envía como parámetro a otro método).

De hecho, la forma más rápida y correcta de codificar esta lectura de una AnsiString partir del contenido es:

s := ''''; SetLength(s,Count); DiskStream.Read(pointer(s)^,Count);

o

SetString(s,nil,Count); DiskStream.Read(pointer(s)^,Count);

La segunda versión es igual a la primera, pero con una línea menos.

Establecer s en '''' llamará a FreeMem()+AllocMem() lugar de ReallocMem() en SetLength() , por lo que evitará que una llamada se move() , y por lo tanto será un poco más rápido.

De hecho, la llamada RTL UniqueString?() por s[1] será muy rápida, ya que ya ha llamado a SetLength() antes de llamarla: por lo tanto, s ya es único, y la llamada RTL UniqueString?() casi inmediatamente. Después del perfilado, no hay mucha diferencia de velocidad entre las dos versiones: casi todo el tiempo se dedica a la asignación de cadenas y al contenido moviéndose desde el disco. Quizás s[1] se encuentra para ser más "pascalish".