Increment an integer without SET
Moderator: DosItHelp
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Increment an integer without SET
hi to all,
Does anyone know how to increment a variable that contains the representation of an integer?
I would suffice the increase of 1 or a few units
I would avoid the use of the SET (or the SET / A) and if possible use only one or two expansions (or if there is a chance even three). So that is faster than the use of the "SET".
I need to numbers ranging from 0 to 8191 (theoretical max for a environment variable for DOS BATCH)
Thanks
Einstein1969
Does anyone know how to increment a variable that contains the representation of an integer?
I would suffice the increase of 1 or a few units
I would avoid the use of the SET (or the SET / A) and if possible use only one or two expansions (or if there is a chance even three). So that is faster than the use of the "SET".
I need to numbers ranging from 0 to 8191 (theoretical max for a environment variable for DOS BATCH)
Thanks
Einstein1969
Re: Increment an integer without SET
I can't see the sense of avoiding set /a
What is wrong with
What is wrong with
Code: Select all
set /a myCounter=0
for /F %%L in (text.txt) DO (
set /a myCounter+=1
)
-
- Expert
- Posts: 1166
- Joined: 06 Sep 2013 21:28
- Location: Virginia, United States
Re: Increment an integer without SET
I'd be really curious to see how somebody could change the value of a variable without using SET.
Closest thing I can think would be
Closest thing I can think would be
Code: Select all
for /L %%A in (0,1,8191) do (
rem whatever you're doing with %%A
)
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Increment an integer without SET
Ok. I have formuled the question wrong! You are right!
I use this code for change the content of string:
one_char_change:
It is possibile cut the "set /a Pos2=Pos+1" or "set last=!s:~%Pos%!" and using one SET?
Einstein1969
I use this code for change the content of string:
one_char_change:
Code: Select all
setlocal EnableDelayedExpansion
set s=0123456789
set Pos=4
set newvalue=#
set /a Pos2=Pos+1
set s=!s:~0,%Pos%!!newvalue!!s:~%Pos2%!
echo !s!
rem OR
set s=0123456789
set Pos=4
set newvalue=#
set last=!s:~%Pos%!
set s=!s:~0,%Pos%!!newvalue!!last:~1!
echo !s!
It is possibile cut the "set /a Pos2=Pos+1" or "set last=!s:~%Pos%!" and using one SET?
Einstein1969
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Increment an integer without SET
jeb wrote:I can't see the sense of avoiding set /a
For performance reason (if we can do it)
Re: Increment an integer without SET
einstein1969 wrote:jeb wrote:I can't see the sense of avoiding set /a
For performance reason (if we can do it)
If you are looking for performance then why are you using batch?
Even an interpreted basic program will blow batch out of the water for speed.
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Increment an integer without SET
foxidrive wrote:einstein1969 wrote:jeb wrote:I can't see the sense of avoiding set /a
For performance reason (if we can do it)
If you are looking for performance then why are you using batch?
Even an interpreted basic program will blow batch out of the water for speed.
you are right!
I could certainly do the same thing in assembler or any other language or script interpreter etc.
But I'm delving into the batch dos.
Einstein1969
Re: Increment an integer without SET
SET is a CMD - internal command. That means it's as fast as a command can be. No idea why you are thinking it would cause a bad performance in your batch code. If you want to improve the peformance of a batch code the try to avoid external commands (at least try to avoid calling them several times for the same reason).
That code will separate the commands that are listed in HELP:
Regards
aGerman
That code will separate the commands that are listed in HELP:
Code: Select all
@echo off &setlocal
set /a int=0, ext=0
for /f %%i in ('help^|findstr /rbc:"[A-Z][ABCDEFGHIJKLMNOPQRSTUVWXYZ]"') do (
for /f "tokens=1,2 delims=?" %%j in ("%%i.exe?%%i.com") do (
if "%%~$PATH:j%%~$PATH:k"=="" (
call :out %%i
) else (
set /a ext+=1
echo %%i "%%~$PATH:j%%~$PATH:k"
)
)
)
echo(
echo internal %int%
echo external %ext%
pause>nul
goto :eof
:out
set /a int+=1
set "line=%1 "
echo %line:~,50% - internal
goto :eof
Regards
aGerman
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Increment an integer without SET
Thank you for the wise suggestion, but I'm using at the moment few external commands. I'll probably have to revise the logic to break down the problem of declining performance.
This script is phenomenal! It will take me a double cup of coffee to figure out how do you generate the list.
Anyway back to the problem of performance. I saw that SET is fast but sometimes it is slower than an expansion. So I thought that populate a variable upstream then use it would be good for performance. My goal is both qualitative (functional) and performance.
Einstein1969
This script is phenomenal! It will take me a double cup of coffee to figure out how do you generate the list.
Anyway back to the problem of performance. I saw that SET is fast but sometimes it is slower than an expansion. So I thought that populate a variable upstream then use it would be good for performance. My goal is both qualitative (functional) and performance.
Einstein1969
Re: Increment an integer without SET
I'm using at the moment few external commands
You can't avoid it. What I actually meant is that you could use COPY instead of XCOPY if you simply have to copy a file. Or that you could apply FINDSTR to a file / a set of files instead of applying it to each line / each file separately.
The reason why it decreases the performance enormously is that Windows needs some time to load the process. Depending on RAM, number of CPUs, clocking, current CPU usage etc. it wastes approx. 200ms each time you call an external command.
It will take me a double cup of coffee to figure out how do you generate the list.
Actually it's very simple. I process the list of commands that the HELP command displays. I append .exe and .com to the commands and use the ~$path: modifier of FOR variables to check if such a file can be found in the PATH environment.
Regards
aGerman
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Increment an integer without SET
aGerman wrote:I'm using at the moment few external commands
You can't avoid it. What I actually meant is that you could use COPY instead of XCOPY if you simply have to copy a file. Or that you could apply FINDSTR to a file / a set of files instead of applying it to each line / each file separately.
The reason why it decreases the performance enormously is that Windows needs some time to load the process. Depending on RAM, number of CPUs, clocking, current CPU usage etc. it wastes approx. 200ms each time you call an external command.It will take me a double cup of coffee to figure out how do you generate the list.
Actually it's very simple. I process the list of commands that the HELP command displays. I append .exe and .com to the commands and use the ~$path: modifier of FOR variables to check if such a file can be found in the PATH environment.
Regards
aGerman
Thanks for explain aGerman.
Yes, I can't avoid. But depend of nature of application. There are application that use 200ms for call external program and 20000ms of internal command. And if i reduce of 40% than i'm happy.
Meanwhile i have find a way.... difficult to follow
for value from 0 to 8 (I dread to think how to get to 8192)
result:
Code: Select all
Without SET /A
#123456789
##23456789
###3456789
####456789
#####56789
######6789
#######789
########89
#########9
With SET /A
#123456789
##23456789
###3456789
####456789
#####56789
######6789
#######789
########89
#########9
Code: Select all
@echo off & setlocal EnableDelayedExpansion
set newvalue=#
set pos2=1234567890
set s=0123456789
echo Without SET /A
For /L %%# in (0,1,8) do (
rem set /a Pos2=Pos+1
for %%A in ("!Pos2:~%%#,1!") do set s=!s:~0,%%#!!newvalue!!s:~%%~A!
echo !s!
)
set s=0123456789
echo(
echo With SET /A
For /L %%# in (0,1,8) do (
set /a Pos2=%%#+1
for %%A in (!Pos2!) do set s=!s:~0,%%#!!newvalue!!s:~%%A! <---can optimize this?
echo !s!
)
Timing:
Code: Select all
Environ Grow Change a string with:
Size Environ SET/A +1 EXP_EQ. GAIN
----------------------------------------------------
4907 0.00 2.65 2.17 19%
15451 0.01 3.98 2.89 28%
36052 0.02 7.22 4.66 36%
77252 0.06 15.68 9.74 38%
159705 0.27 33.85 19.14 44%
How do I make the rest of the numbers?
Einstein1969
Re: Increment an integer without SET
Perhaps is this what you want?
Code: Select all
@echo off & setlocal EnableDelayedExpansion
for /L %%a in (0,1,9) do (
set inc[!last!]=%%a
set last=%%a
)
set newvalue=#
set s=0123456789
echo REALLY Without SET /A
For /L %%# in (0,1,8) do (
for %%A in (!inc[%%#]!) do set s=!s:~0,%%#!!newvalue!!s:~%%A!
echo !s!
)
Re: Increment an integer without SET
More speedy:
Code: Select all
Echo #123456789
Echo ##23456789
Echo ###3456789
Echo ####456789
Echo #####56789
Echo ######6789
Echo #######789
Echo ########89
Echo #########9
-
- Expert
- Posts: 960
- Joined: 15 Jun 2012 13:16
- Location: Italy, Rome
Re: Increment an integer without SET
@Aacini
Thanks Aacini , this work but I had already considered the use of "classic" vector . But for performance issues I'm trying to use as few variables as possible. Without going to the extreme dictated by carlos: D I found a solution by using a mechanism such as the "map and lookup" described on the site even though it is currently limited to much lower values than 8192 which was my original goal.
However, for the moment, your solution is the best because overcomes the limitation of 8192
ingenious use of the "last" in your code
my last code:
@carlos
nice
I'm seriously thinking that it is the best solution at the time. Just prepare before everything and then use it at the appropriate time. Brilliant!
But to get the result must always pass for processing ...
Use the best environment I think is one of my goals or even a presentiment that it is a path with no way out ...
Einstein1969
Aacini wrote:Perhaps is this what you want?Code: Select all
@echo off & setlocal EnableDelayedExpansion
for /L %%a in (0,1,9) do (
set inc[!last!]=%%a
set last=%%a
)
set newvalue=#
set s=0123456789
echo REALLY Without SET /A
For /L %%# in (0,1,8) do (
for %%A in (!inc[%%#]!) do set s=!s:~0,%%#!!newvalue!!s:~%%A!
echo !s!
)
Thanks Aacini , this work but I had already considered the use of "classic" vector . But for performance issues I'm trying to use as few variables as possible. Without going to the extreme dictated by carlos: D I found a solution by using a mechanism such as the "map and lookup" described on the site even though it is currently limited to much lower values than 8192 which was my original goal.
However, for the moment, your solution is the best because overcomes the limitation of 8192
ingenious use of the "last" in your code
my last code:
Code: Select all
@echo off & setlocal EnableDelayedExpansion
set newvalue=#
rem create like this ....20-20#21-21#22-22#23-23#24-24#25-25#26-26#27-27#28-28#29-....
set newpos2=
For /L %%# in (0,1,98) do (
set /a ns=%%#+1
set ns=0!ns!
set n=0%%#
set n=!n:~-2!#!ns:~-2!-
set newpos2=!newpos2!!n!
)
rem echo !newpos2!
rem test
set s=0123456789abcdefghijklhmenopqrstuvwxyz
set pos=19
for /f "delims=-" %%t in ("!newpos2:*%pos%#=!") do set s=!s:~0,%pos%!!newvalue!!s:~%%t!
echo !s!
@carlos
nice
I'm seriously thinking that it is the best solution at the time. Just prepare before everything and then use it at the appropriate time. Brilliant!
But to get the result must always pass for processing ...
Use the best environment I think is one of my goals or even a presentiment that it is a path with no way out ...
Einstein1969
Re: Increment an integer without SET
I think that the task can coded in many ways, But the best principle for programming is "Programming only that you need". The really task is print the number of sharp.
In this case, we have a union in that in row 1 we print 1 sharp, in row 2 we print 2 sharps.
In all the task we need index variables, but because you need not use a environment variable, we choose a for /l variable.
And also we have other option, use a counter for print 1 sharp, for example if we need print 3 asterisk do for /l %%# in (1,1,3) do print # or have a hardcoded variable for print %var:~1,3%
Then there are variants of programming.
This is a option:
and other variant:
In this case, we have a union in that in row 1 we print 1 sharp, in row 2 we print 2 sharps.
In all the task we need index variables, but because you need not use a environment variable, we choose a for /l variable.
And also we have other option, use a counter for print 1 sharp, for example if we need print 3 asterisk do for /l %%# in (1,1,3) do print # or have a hardcoded variable for print %var:~1,3%
Then there are variants of programming.
This is a option:
Code: Select all
@Echo Off
SetLocal EnableDelayedExpansion
Set num=_123456789
Set rep=_#########
For /L %%R in (1,1,9) Do Echo !rep:~1,%%R!!num:~%%R!
Pause
and other variant:
Code: Select all
@Echo Off
SetLocal EnableDelayedExpansion
Set num=123456789
Set rep=#########
For /L %%R in (0,1,8) Do Echo #!rep:~0,%%R!!num:~%%R!
Pause