Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Un fulmine sulla scrivania, Corsair Sabre v2 Pro ridefinisce la velocità nel gaming
Un fulmine sulla scrivania, Corsair Sabre v2 Pro ridefinisce la velocità nel gaming
Questo mouse ultraleggero, con soli 36 grammi di peso, è stato concepito per offrire un'esperienza di gioco di alto livello ai professionisti degli FPS, grazie al polling rate a 8.000 Hz e a un sensore ottico da 33.000 DPI. La recensione esplora ogni dettaglio di questo dispositivo di gioco, dalla sua agilità estrema alle specifiche tecniche che lo pongono un passo avanti
Nokia Innovation Day 2025: l’Europa ha bisogno di campioni nelle telecomunicazioni
Nokia Innovation Day 2025: l’Europa ha bisogno di campioni nelle telecomunicazioni
Dal richiamo di Enrico Letta alla necessità di completare il mercato unico entro il 2028 alla visione di Nokia sul ruolo dell’IA e delle reti intelligenti, il Nokia Innovation Day 2025 ha intrecciato geopolitica e tecnologia, mostrando a Vimercate come la ricerca italiana contribuisca alle sfide globali delle telecomunicazioni
Sottile, leggero e dall'autonomia WOW: OPPO Reno14 F conquista con stile e sostanza
Sottile, leggero e dall'autonomia WOW: OPPO Reno14 F conquista con stile e sostanza
OPPO Reno14 F 5G si propone come smartphone di fascia media con caratteristiche equilibrate. Il device monta processore Qualcomm Snapdragon 6 Gen 1, display AMOLED da 6,57 pollici a 120Hz, tripla fotocamera posteriore con sensore principale da 50MP e generosa batteria da 6000mAh con ricarica rapida a 45W. Si posiziona come alternativa accessibile nella gamma Reno14, proponendo un design curato e tutto quello che serve per un uso senza troppe preoccupazioni.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 21-10-2008, 23:11   #1
Oceans11
Senior Member
 
L'Avatar di Oceans11
 
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
[JAVA] reverse string un pò particolare

Volevo postare questo pezzo di codice che fa il reverse di una stringa tramite xor:

Codice:
public static String reverse(String toReverse) {
   char[] array = toReverse.toCharArray();
   int len = str.length() - 1;
   for (int i = 0; i < len; i++, len--) {
      array[i] ^= array[len];
      array[len] ^= array[i];
      array[i] ^= array[len];
   }
   return new String(array);
}
Sono ben accette spiegazioni e commenti, o anche solo un'occhiata .
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes]
"Pirating software? Choose Microsoft!"
Oceans11 è offline   Rispondi citando il messaggio o parte di esso
Old 21-10-2008, 23:29   #2
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
Quote:
Originariamente inviato da Oceans11 Guarda i messaggi
Volevo postare questo pezzo di codice che fa il reverse di una stringa tramite xor:

Codice:
public static String reverse(String toReverse) {
   char[] array = toReverse.toCharArray();
   int len = str.length() - 1;
   for (int i = 0; i < len; i++, len--) {
      array[i] ^= array[len];
      array[len] ^= array[i];
      array[i] ^= array[len];
   }
   return new String(array);
}
Sono ben accette spiegazioni e commenti, o anche solo un'occhiata .
È una tecnica utilizzata per scambiare il valore di due variabili senza far uso di una variabile temporanea d'appoggio. Per esempio(è in C ma in Java dovrebbe essere uguale):

Codice:
int x = 5;
int y = 8;
x ^= y;
y ^= x;
x ^= y;
Alla fine x conterrà 8 e y 5. Dovrebbe essere anche più veloce, data l'efficienza degli operatori sui bit(ma non l'ho provato).

Ultima modifica di Vincenzo1968 : 21-10-2008 alle 23:37.
Vincenzo1968 è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 00:01   #3
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Quote:
Originariamente inviato da Vincenzo1968 Guarda i messaggi
Codice:
int x = 5;
int y = 8;
x ^= y;
y ^= x;
x ^= y;
Alla fine x conterrà 8 e y 5. Dovrebbe essere anche più veloce, data l'efficienza degli operatori sui bit(ma non l'ho provato).
No Vincenzo.
E' piu' lenta della versione classica con variabile d'appoggio.
Era utile (ogni tanto) una volta, in assembly, in carenza di registri.
Ma oggi non e' consigliabile.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 00:51   #4
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
Quote:
Originariamente inviato da gugoXX Guarda i messaggi
No Vincenzo.
E' piu' lenta della versione classica con variabile d'appoggio.
Era utile (ogni tanto) una volta, in assembly, in carenza di registri.
Ma oggi non e' consigliabile.
Vero. Ho fatto la prova:



Codice:
#include <stdio.h>
#include <time.h>

int main()
{
	clock_t c_start, c_end;
	int k;
	int tmp;

	int x = 5;
	int y = 8;

	c_start = clock();
	for ( k = 0; k < 100000001; k++ )
	{
		x ^= y;
		y ^= x;
		x ^= y;
	}
	c_end = clock();

	printf("\nx -> %d\ny -> %d\n", x, y);

	printf("\nTempo 1 -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC);

	c_start = clock();
	for ( k = 0; k < 100000001; k++ )
	{
		tmp = x;
		x = y;
		y = tmp;
	}
	c_end = clock();

	printf("\nx -> %d\ny -> %d\n", x, y);

	printf("\nTempo 2 -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC);

	return 0;
}
Vincenzo1968 è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 01:01   #5
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Quote:
Originariamente inviato da Vincenzo1968 Guarda i messaggi
Vero. Ho fatto la prova:



...
Se puoi stampa il codice assembly di entrambe le soluzioni, e commentiamo.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 09:51   #6
Ziosilvio
Moderatore
 
L'Avatar di Ziosilvio
 
Iscritto dal: Nov 2003
Messaggi: 16211
Quote:
Originariamente inviato da Vincenzo1968 Guarda i messaggi
È una tecnica utilizzata per scambiare il valore di due variabili senza far uso di una variabile temporanea d'appoggio. Per esempio(è in C ma in Java dovrebbe essere uguale):

Codice:
int x = 5;
int y = 8;
x ^= y;
y ^= x;
x ^= y;
Alla fine x conterrà 8 e y 5. Dovrebbe essere anche più veloce, data l'efficienza degli operatori sui bit(ma non l'ho provato).
Era:
Codice:
x ^= y ^= x ^= y;
Sul mio computer è talmente veloce che la funzione clock non riesce a distinguere il tempo d'inizio dal tempo di fine
Ovviamente, funziona solo se x e y sono variabili intere: int, char, long...
__________________
Ubuntu è un'antica parola africana che significa "non so configurare Debian" Chi scherza col fuoco si brucia.
Scienza e tecnica: Matematica - Fisica - Chimica - Informatica - Software scientifico - Consulti medici
REGOLAMENTO DarthMaul = Asus FX505 Ryzen 7 3700U 8GB GeForce GTX 1650 Win10 + Ubuntu

Ultima modifica di Ziosilvio : 22-10-2008 alle 09:57.
Ziosilvio è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 14:13   #7
incipit1970
Member
 
Iscritto dal: Mar 2007
Messaggi: 298
Quote:
Originariamente inviato da Ziosilvio Guarda i messaggi
Era:
Codice:
x ^= y ^= x ^= y;
Sul mio computer è talmente veloce che la funzione clock non riesce a distinguere il tempo d'inizio dal tempo di fine
Ovviamente, funziona solo se x e y sono variabili intere: int, char, long...
Per inefficiente che sia l'assembler generato dal compilatore, un'assegnazione non può richiedere più di qualche ciclo di clock, ed in un qualsiasi processore moderno ogni ciclo di clock dura meno di un milliardesimo di secondo, quindi si parla sempre di quantità infime. Infatti, il codice di Vincenzo1968 fa 100 millioni di assegnazioni per ognuno dei codici, ed il tempo totale nel peggiore dei due casi è di appena un decimo di secondo. la differenza si apprezza solo facendo millioni di operazioni, una sola non smuove neanche il contatore. Le date di solito arrivano ad una risoluzione di un millesimo di secondo, ma è un tempo enorme per misurare una istruzione di cpu.

Se devi muovere solo qualche byte, vanno bene entrambi i modi, ma se le operazioni vanno fatte su quantità massicce di dati, allora meglio scegliere l'operazione più veloce, a parità di cose.
incipit1970 è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 14:34   #8
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
Eqque qua:



Codice:
#include <stdio.h>
#include <time.h>

int main()
{
	clock_t c_start, c_end;
	int k;
	int tmp;

	int x = 5;
	int y = 8;


	c_start = clock();
	for ( k = 0; k < 1000000001; k++ )
	{
		x ^= y ^= x ^= y;
	}
	c_end = clock();

	printf("\nx -> %d\ny -> %d\n", x, y);

	printf("\nTempo 0 -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC);


	c_start = clock();
	for ( k = 0; k < 1000000001; k++ )
	{
		x ^= y;
		y ^= x;
		x ^= y;
	}
	c_end = clock();

	printf("\nx -> %d\ny -> %d\n", x, y);

	printf("\nTempo 1 -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC);

	c_start = clock();
	for ( k = 0; k < 1000000001; k++ )
	{
		tmp = x;
		x = y;
		y = tmp;
	}
	c_end = clock();

	printf("\nx -> %d\ny -> %d\n", x, y);

	printf("\nTempo 2 -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC);

	return 0;
}
e questo è l'assembly generato dal compilatore:

Codice:
; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.21022.08 

	TITLE	c:\Progetti Visual Studio\Progetti visual Studio 2008\C++\MyProjects\HtmlIt\ArrayTree\ArrayTree\ArrayTree.c
	.686P
	.XMM
	include listing.inc
	.model	flat

INCLUDELIB OLDNAMES

PUBLIC	??_C@_03NHELKHFK@?$CFd?7?$AA@			; `string'
PUBLIC	??_C@_00CNPNBAHC@?$AA@				; `string'
PUBLIC	??_C@_0BC@BJMPBCEC@?6x?5?9?$DO?5?$CFd?6y?5?9?$DO?5?$CFd?6?$AA@ ; `string'
PUBLIC	??_C@_0BL@IABJBOLO@?6Tempo?50?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@ ; `string'
PUBLIC	??_C@_0BL@OFHOCFPI@?6Tempo?51?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@ ; `string'
PUBLIC	??_C@_0BL@EKNHGIDC@?6Tempo?52?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@ ; `string'
EXTRN	@__security_check_cookie@4:PROC
EXTRN	__imp__puts:PROC
EXTRN	__imp__printf:PROC
EXTRN	__imp__clock:PROC
;	COMDAT ??_C@_0BL@EKNHGIDC@?6Tempo?52?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@
CONST	SEGMENT
??_C@_0BL@EKNHGIDC@?6Tempo?52?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@ DB 0aH, 'T'
	DB	'empo 2 -> %5.5f secondi', 0aH, 00H		; `string'
CONST	ENDS
;	COMDAT ??_C@_0BL@OFHOCFPI@?6Tempo?51?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@
CONST	SEGMENT
??_C@_0BL@OFHOCFPI@?6Tempo?51?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@ DB 0aH, 'T'
	DB	'empo 1 -> %5.5f secondi', 0aH, 00H		; `string'
CONST	ENDS
;	COMDAT ??_C@_0BL@IABJBOLO@?6Tempo?50?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@
CONST	SEGMENT
??_C@_0BL@IABJBOLO@?6Tempo?50?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@ DB 0aH, 'T'
	DB	'empo 0 -> %5.5f secondi', 0aH, 00H		; `string'
CONST	ENDS
;	COMDAT ??_C@_0BC@BJMPBCEC@?6x?5?9?$DO?5?$CFd?6y?5?9?$DO?5?$CFd?6?$AA@
CONST	SEGMENT
??_C@_0BC@BJMPBCEC@?6x?5?9?$DO?5?$CFd?6y?5?9?$DO?5?$CFd?6?$AA@ DB 0aH, 'x'
	DB	' -> %d', 0aH, 'y -> %d', 0aH, 00H		; `string'
CONST	ENDS
;	COMDAT ??_C@_00CNPNBAHC@?$AA@
CONST	SEGMENT
??_C@_00CNPNBAHC@?$AA@ DB 00H				; `string'
CONST	ENDS
;	COMDAT ??_C@_03NHELKHFK@?$CFd?7?$AA@
CONST	SEGMENT
??_C@_03NHELKHFK@?$CFd?7?$AA@ DB '%d', 09H, 00H		; `string'
CONST	ENDS
PUBLIC	__real@408f400000000000
PUBLIC	_main
EXTRN	__fltused:DWORD
;	COMDAT __real@408f400000000000
; File c:\progetti visual studio\progetti visual studio 2008\c++\myprojects\htmlit\arraytree\arraytree\arraytree.c
CONST	SEGMENT
__real@408f400000000000 DQ 0408f400000000000r	; 1000
; Function compile flags: /Ogtpy
CONST	ENDS
;	COMDAT _main
_TEXT	SEGMENT
tv203 = -4						; size = 4
tv197 = -4						; size = 4
tv190 = -4						; size = 4
_c_start$ = -4						; size = 4
_main	PROC						; COMDAT

; 38   : {

	push	ebp
	mov	ebp, esp
	and	esp, -64				; ffffffc0H
	sub	esp, 48					; 00000030H
	push	ebx

; 39   : 	clock_t c_start, c_end;
; 40   : 	int k;
; 41   : 	int tmp;
; 42   : 
; 43   : 	int x = 5;
; 44   : 	int y = 8;
; 45   : 
; 46   : 
; 47   : 	c_start = clock();

	mov	ebx, DWORD PTR __imp__clock
	push	ebp
	push	esi
	push	edi
	mov	esi, 5
	lea	edi, DWORD PTR [esi+3]
	call	ebx
	mov	DWORD PTR _c_start$[esp+64], eax
	mov	eax, 1000000001				; 3b9aca01H
$LL9@main:

; 48   : 	for ( k = 0; k < 1000000001; k++ )
; 49   : 	{
; 50   : 		x ^= y ^= x ^= y;

	xor	esi, edi
	xor	edi, esi
	xor	esi, edi
	sub	eax, 1
	jne	SHORT $LL9@main

; 51   : 	}
; 52   : 	c_end = clock();

	call	ebx

; 53   : 
; 54   : 	printf("\nx -> %d\ny -> %d\n", x, y);

	mov	ebx, DWORD PTR __imp__printf
	push	edi
	push	esi
	push	OFFSET ??_C@_0BC@BJMPBCEC@?6x?5?9?$DO?5?$CFd?6y?5?9?$DO?5?$CFd?6?$AA@
	mov	ebp, eax
	call	ebx

; 55   : 
; 56   : 	printf("\nTempo 0 -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC);

	sub	ebp, DWORD PTR _c_start$[esp+76]
	add	esp, 4
	mov	DWORD PTR tv203[esp+72], ebp
	fild	DWORD PTR tv203[esp+72]
	fdiv	QWORD PTR __real@408f400000000000
	fstp	QWORD PTR [esp]
	push	OFFSET ??_C@_0BL@IABJBOLO@?6Tempo?50?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@
	call	ebx

; 57   : 
; 58   : 
; 59   : 	c_start = clock();

	mov	ebp, DWORD PTR __imp__clock
	add	esp, 12					; 0000000cH
	call	ebp
	mov	DWORD PTR _c_start$[esp+64], eax
	mov	eax, 1000000001				; 3b9aca01H
$LL6@main:

; 60   : 	for ( k = 0; k < 1000000001; k++ )
; 61   : 	{
; 62   : 		x ^= y;

	xor	esi, edi

; 63   : 		y ^= x;

	xor	edi, esi

; 64   : 		x ^= y;

	xor	esi, edi
	sub	eax, 1
	jne	SHORT $LL6@main

; 65   : 	}
; 66   : 	c_end = clock();

	call	ebp

; 67   : 
; 68   : 	printf("\nx -> %d\ny -> %d\n", x, y);

	push	edi
	push	esi
	push	OFFSET ??_C@_0BC@BJMPBCEC@?6x?5?9?$DO?5?$CFd?6y?5?9?$DO?5?$CFd?6?$AA@
	mov	ebp, eax
	call	ebx

; 69   : 
; 70   : 	printf("\nTempo 1 -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC);

	sub	ebp, DWORD PTR _c_start$[esp+76]
	add	esp, 4
	mov	DWORD PTR tv197[esp+72], ebp
	fild	DWORD PTR tv197[esp+72]
	fdiv	QWORD PTR __real@408f400000000000
	fstp	QWORD PTR [esp]
	push	OFFSET ??_C@_0BL@OFHOCFPI@?6Tempo?51?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@
	call	ebx
	add	esp, 12					; 0000000cH

; 71   : 
; 72   : 	c_start = clock();

	call	DWORD PTR __imp__clock
	mov	DWORD PTR _c_start$[esp+64], eax
	mov	eax, 1000000001				; 3b9aca01H
$LL3@main:

; 73   : 	for ( k = 0; k < 1000000001; k++ )

	sub	eax, 1

; 74   : 	{
; 75   : 		tmp = x;

	mov	ebp, esi

; 76   : 		x = y;

	mov	esi, edi

; 77   : 		y = tmp;

	mov	edi, ebp
	jne	SHORT $LL3@main

; 78   : 	}
; 79   : 	c_end = clock();

	call	DWORD PTR __imp__clock

; 80   : 
; 81   : 	printf("\nx -> %d\ny -> %d\n", x, y);

	push	ebp
	push	esi
	push	OFFSET ??_C@_0BC@BJMPBCEC@?6x?5?9?$DO?5?$CFd?6y?5?9?$DO?5?$CFd?6?$AA@
	mov	edi, eax
	call	ebx

; 82   : 
; 83   : 	printf("\nTempo 2 -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC);

	sub	edi, DWORD PTR _c_start$[esp+76]
	add	esp, 4
	mov	DWORD PTR tv190[esp+72], edi
	fild	DWORD PTR tv190[esp+72]
	fdiv	QWORD PTR __real@408f400000000000
	fstp	QWORD PTR [esp]
	push	OFFSET ??_C@_0BL@EKNHGIDC@?6Tempo?52?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@
	call	ebx
	add	esp, 12					; 0000000cH

; 84   : 
; 85   : 	return 0;
; 86   : }

	pop	edi
	xor	eax, eax
	pop	esi
	pop	ebp
	pop	ebx
	mov	esp, ebp
	pop	ebp
	ret	0
_main	ENDP
_TEXT	ENDS
END
Ho aggiunto uno zero: 1000000001.
Domanda: un buon libro per imparare l'assembly?

P.S. Questa è la mia macchina:

Codice:
AMD Athlon(tm) 64 X2
Dual Core Processor 4800+
2.50 GHz
896 MB di RAM

Microsoft Windows XP Professional (32 bit)
Service Pack 3

Ultima modifica di Vincenzo1968 : 22-10-2008 alle 14:36.
Vincenzo1968 è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 15:14   #9
shinya
Senior Member
 
L'Avatar di shinya
 
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
Quote:
Originariamente inviato da Oceans11 Guarda i messaggi
Volevo postare questo pezzo di codice che fa il reverse di una stringa tramite xor:
...

Sono ben accette spiegazioni e commenti, o anche solo un'occhiata .
Non vorrei dire una caxxata, ma il tuo metodo potrebbe avere qualche problema con stringhe unicode. Non ho tempo di testarlo e verificare però.

Che ne dici di...
Codice:
new StringBuilder(toReverse).reverse().toString()
??
shinya è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 15:56   #10
incipit1970
Member
 
Iscritto dal: Mar 2007
Messaggi: 298
Quote:
Originariamente inviato da Vincenzo1968 Guarda i messaggi
Domanda: un buon libro per imparare l'assembly?
Ah, l'assembler... saranno 10-15 anni che non lo uso... un po' ostico, ma che sensazione di benessere quando assemblavi il programma e vedevi un eseguibile di 1-2Kb...

Come linguaggio è facilissimo (almeno io lo trovo facile, c'è chi direbbe il contrario), ma richiede una buona conoscenza dell'architettura che c'è dietro. Ci sono diverse intro in giro per internet, uno può essere questo, che ha il vantaggio di essere in italiano.

Ma dal mio punto di vista il punto di riferimento resta l'Intel Software Developer's Manual per le piattaforme ia32 ed ia64, non so se anche AMD abbia documentazione sul proprio set di istruzioni, ma suppongo di si. Ma non è esattamente introduttivo...

Purtroppo, di questi tempi l'assembler è quasi un hobby, difficilmente si trova spazio per utilizzarlo su progetti "reali", eccetto se ti occupi di elettronica o programmazione di basso livello.
incipit1970 è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 16:01   #11
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Quote:
Originariamente inviato da shinya Guarda i messaggi
Non vorrei dire una caxxata, ma il tuo metodo potrebbe avere qualche problema con stringhe unicode. Non ho tempo di testarlo e verificare però.

Che ne dici di...
Codice:
new StringBuilder(toReverse).reverse().toString()
??
Anche cosi', sempre in C#, dovendo scrivere in output su file come richiesto
Codice:
            string ToPrint = "PippoPlutoPaperino";     
       
            StreamWriter output = new StreamWriter("output.txt");
            output.Write(ToPrint);           
            output.Write(ToPrint.Reverse());
            output.Close();
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 16:33   #12
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
Quote:
Originariamente inviato da incipit1970 Guarda i messaggi
Ah, l'assembler... saranno 10-15 anni che non lo uso... un po' ostico, ma che sensazione di benessere quando assemblavi il programma e vedevi un eseguibile di 1-2Kb...

Come linguaggio è facilissimo (almeno io lo trovo facile, c'è chi direbbe il contrario), ma richiede una buona conoscenza dell'architettura che c'è dietro. Ci sono diverse intro in giro per internet, uno può essere questo, che ha il vantaggio di essere in italiano.

Ma dal mio punto di vista il punto di riferimento resta l'Intel Software Developer's Manual per le piattaforme ia32 ed ia64, non so se anche AMD abbia documentazione sul proprio set di istruzioni, ma suppongo di si. Ma non è esattamente introduttivo...

Purtroppo, di questi tempi l'assembler è quasi un hobby, difficilmente si trova spazio per utilizzarlo su progetti "reali", eccetto se ti occupi di elettronica o programmazione di basso livello.
Ciao Incipit,

grazie per la risposta e per il link. Non voglio imparare l'assembly per realizzare applicazioni complesse ma vorrei, almeno, capire il codice generato dal compilatore.

Vincenzo1968 è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 17:05   #13
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
Quote:
Originariamente inviato da gugoXX Guarda i messaggi
Se puoi stampa il codice assembly di entrambe le soluzioni, e commentiamo.
Ohé Gugo(ma anche Incipit e chiunque se ne intenda),

a proposito di imparare l'assembly, un commento sul codice che ho postato?

Ultima modifica di Vincenzo1968 : 22-10-2008 alle 17:09.
Vincenzo1968 è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 17:25   #14
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Quote:
Originariamente inviato da Vincenzo1968 Guarda i messaggi
Ohé Gugo(ma anche Incipit e chiunque se ne intenda),

a proposito di imparare l'assembly, un commento sul codice che ho postato?
Ciao.
Si', purtroppo e' troppo ottimizzato, nel senso che il C ha pensato bene di tenere le variabili su registri.
Normalmente quando si scambiano i valori delle due variabili si fa qualcosa, e quindi non possono essere tenute su registri, ma occorre passare in memoria.
Invece qui non si e' fatto nulla, il C l'ha capito ed ha tagliato.
L'effetto del rallentare e' solo dovuto al fatto che le XOR si accoppiano meno bene che le MOV (e comunque un po' si vede)
Se all'interno del ciclo (in entrambi i casi), provi a chiamare una funzione che usa X e Y, allora forse riusciamo a vedere meglio il problema.
non so, una funzione che sperabilmente non possa essere messa come __inline automaticamente, quindi decorosamente complessa.
Oppure puoi provare a chiedere indirettamente al C di non considerare le variabili come ottimizzabili in registri. Se non sbaglio c'e' anche in C la keyword
volatile

[code]
volatile int x=5;
volatile int y=8;
[code]

Purtroppo non ho un compilatore C sottomano per provare io direttamente.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 18:01   #15
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
Quote:
Originariamente inviato da gugoXX Guarda i messaggi
Ciao.
Si', purtroppo e' troppo ottimizzato, nel senso che il C ha pensato bene di tenere le variabili su registri.
Normalmente quando si scambiano i valori delle due variabili si fa qualcosa, e quindi non possono essere tenute su registri, ma occorre passare in memoria.
Invece qui non si e' fatto nulla, il C l'ha capito ed ha tagliato.
L'effetto del rallentare e' solo dovuto al fatto che le XOR si accoppiano meno bene che le MOV (e comunque un po' si vede)
Se all'interno del ciclo (in entrambi i casi), provi a chiamare una funzione che usa X e Y, allora forse riusciamo a vedere meglio il problema.
non so, una funzione che sperabilmente non possa essere messa come __inline automaticamente, quindi decorosamente complessa.
Oppure puoi provare a chiedere indirettamente al C di non considerare le variabili come ottimizzabili in registri. Se non sbaglio c'e' anche in C la keyword
volatile

[code]
volatile int x=5;
volatile int y=8;
[code]
Grazie per la risposta ma non ho capito un tubo. Vado a studiarmi un po' l'assembly. Ne riparliamo, eventualmente, tra qualche anno


Quote:
Originariamente inviato da gugoXX Guarda i messaggi
Purtroppo non ho un compilatore C sottomano per provare io direttamente.
Domanda da Grande Inquisitore(con annessi tratti di corda ): e la dll del contest 7 come l'hai compilata? Pensavo tu avessi il compilatore Visual C++
Vincenzo1968 è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 18:12   #16
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Quote:
Originariamente inviato da Vincenzo1968 Guarda i messaggi
Grazie per la risposta ma non ho capito un tubo. Vado a studiarmi un po' l'assembly. Ne riparliamo, eventualmente, tra qualche anno
Va bene studiare, ma qualche anno mi sembra un po' esagerato...
Comunque prova anche solo a dichiarare le due variaibli con il volatile davanti (che non e' l'uccello padulo)


Quote:
Domanda da Grande Inquisitore(con annessi tratti di corda ): e la dll del contest 7 come l'hai compilata? Pensavo tu avessi il compilatore Visual C++
Certo, appunto e' un compilatore di C++ e non di C.
E comunque era a casa e non al lavoro come adesso
(Poi in realta' ce l'avrei anche qui, ma sai...)
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 18:19   #17
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
Quote:
Originariamente inviato da gugoXX Guarda i messaggi
Va bene studiare, ma qualche anno mi sembra un po' esagerato...
Comunque prova anche solo a dichiarare le due variaibli con il volatile davanti (che non e' l'uccello padulo)



Certo, appunto e' un compilatore di C++ e non di C.
E comunque era a casa e non al lavoro come adesso
(Poi in realta' ce l'avrei anche qui, ma sai...)
Io utilizzo Visual Studio 2008 per compilare i miei programmi in C:

Vincenzo1968 è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 21:16   #18
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Quote:
Originariamente inviato da Vincenzo1968 Guarda i messaggi
Io utilizzo Visual Studio 2008 per compilare i miei programmi in C:
Ma pensa te, non sapevo che si potesse fare la retrocompatibilita'.
Ora ci provo quindi.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 21:50   #19
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Codice:
int x;
int y;
int u;
int v;

int main(array<System::String ^> ^args)
{    
    x = 5;
	y = 8;
    /// XOR
    x ^= y;
    y ^= x;
    x ^= y;
	
	printf("%d %d",x,y);

	u = 5;
	v = 8;
	// TMP
    int tmp = u;
    u = v;
    v = tmp;
	
	printf("%d %d",u,v);
            

    return 0;
}
Codice:
             x = 5;
mov         dword ptr ds:[0040A16Ch],5 

	y = 8;
mov         dword ptr ds:[0040A168h],8 

    /// XOR
    x ^= y;
mov         eax,dword ptr ds:[0040A168h] 
xor         dword ptr ds:[0040A16Ch],eax 

    y ^= x;
mov         eax,dword ptr ds:[0040A16Ch] 
xor         dword ptr ds:[0040A168h],eax 

    x ^= y;
mov         eax,dword ptr ds:[0040A168h] 
xor         dword ptr ds:[0040A16Ch],eax 
	
	printf("%d %d",x,y);
push        40311Ch 
push        dword ptr ds:[0040A16Ch] 
push        dword ptr ds:[0040A168h] 
push        1C6B68h 
call        FF9E43C8 
add         esp,10h 
nop              
nop              

	u = 5;
mov         dword ptr ds:[0040A164h],5 
	v = 8;
mov         dword ptr ds:[0040A160h],8 

	// TMP
    int tmp = u;
mov         eax,dword ptr ds:[0040A164h] 
mov         edi,eax 

    u = v;
mov         eax,dword ptr ds:[0040A160h] 
mov         dword ptr ds:[0040A164h],eax 

    v = tmp;
mov         dword ptr ds:[0040A160h],edi 
	
	printf("%d %d",u,v);
push        403124h 
push        dword ptr ds:[0040A164h] 
push        dword ptr ds:[0040A160h] 
push        1C6B68h 
call        FF9E43C8 
add         esp,10h 
nop              
nop
Ecco, come si puo' vedere ciascuna delle istruzioni Xor e' composta da una lettura da memoria e da uno XOR in memoria.
esso equivale a:
Lettura da memoria:
- Una lettura da memoria, con salvataggio del dato dentro il registro EAX
XOR in memoria. Se avessimo voglia di andare a vedere il microcodice di quest'ultimo XOR:
- una ulteriore lettura da memoria con salvataggio su un registro interno 1
- uno XOR tra EAX (quello che avevamo letto nella prima istruzione) e il registro interno 1, con salvataggio del risultato in un altro registro interno 2
- una scrittura dal registro interno 2 alla stessa cella di memoria

Tralasciando l'operazione vera e propria, abbiamo in totale
2 letture e 1 scrittura su memoria per ciascuno dei 3 XOR del codice C
Per un totale di 6 letture e 3 scritture per gestire lo scambio di variabile

Mentre invece le operazioni con variabile d'appoggio abbiamo
un totale di 2 letture da memoria e 2 scritture su memoria.

C'e' una bella differenza.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 22-10-2008, 22:53   #20
Vincenzo1968
Bannato
 
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
Ohé,

ho trovato questi:

http://xoomer.alice.it/ramsoft/asmba...1/summary.html

http://xoomer.alice.it/ramsoft/asmavan/summary.html

http://xoomer.alice.it/ramsoft/win32asm/summary.htm
Vincenzo1968 è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Un fulmine sulla scrivania, Corsair Sabre v2 Pro ridefinisce la velocità nel gaming Un fulmine sulla scrivania, Corsair Sabre v2 Pro...
Nokia Innovation Day 2025: l’Europa ha bisogno di campioni nelle telecomunicazioni Nokia Innovation Day 2025: l’Europa ha bisogno d...
Sottile, leggero e dall'autonomia WOW: OPPO Reno14 F conquista con stile e sostanza Sottile, leggero e dall'autonomia WOW: OPPO Reno...
Destiny Rising: quando un gioco mobile supera il gioco originale Destiny Rising: quando un gioco mobile supera il...
Plaud Note Pro convince per qualità e integrazione, ma l’abbonamento resta un ostacolo Plaud Note Pro convince per qualità e int...
SpaceX guarda ai primi voli orbitali del...
Il prototipo del razzo spaziale riutiliz...
Blue Origin mostra uno spettacolare vide...
Roscosmos: la capsula Bion-M2 è r...
ASUS sperimenta GPU senza connettori di ...
La Cina conquisterà lo spazio ent...
Samsung ha un nuovo entry level: debutta...
Caos nei cieli europei: attacco informat...
Volkswagen ferma la produzione di ID.Buz...
Super sconti del weekend Amazon: 5 novit...
Dreame non si ferma più: tra le n...
Samsung Galaxy Buds3 FE a meno di 95€ su...
Praticamente regalate: 135€ per le Squie...
Si rinnovano i coupon nascosti di settem...
Amazon sconta i componenti: occasioni d'...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 03:34.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v